fix line numbering issues with vala generator - hopefully fixes completion in node...
[roobuilder] / src / Palete / ValaCompileRequest.vala
index 9003526..19beca5 100644 (file)
 
 
 namespace Palete {
-        
+       public enum ValaCompileRequestType {
+               PROP_CHANGE,
+               FILE_CHANGE,
+               PROJECT,
+               RUN
+       }
                
        public class ValaCompileRequest  : Object
        {
-               Project.Gtk project;
-               string target;
-               Spawn? spawn = null;
+               ValaCompileRequestType requestType;
+               
+               public JsRender.JsRender? file = null;
+               JsRender.Node? node = null;
+               JsRender.NodeProp? prop = null;
+               string alt_code = "";
+               string tmpfile = "";
+               Spawn? compiler  = null;
+       ///     ValaCompileQueue? queue = null;
                
-               public signal void onOutput(string str);
        
                public Gee.HashMap<string,GLib.ListStore>? errorByType = null;
                public Gee.HashMap<string,GLib.ListStore>? errorByFile  = null;
                        
        
                public ValaCompileRequest (
-                       Project.Gtk project,
-                       string target
+                       ValaCompileRequestType requestType,
+                       JsRender.JsRender file ,
+                       JsRender.Node? node,
+                       JsRender.NodeProp? prop,
+                       string alt_code = ""
                         
                ) {
-                       this.project =   project;
-                       this.target = target;
+                       this.requestType = requestType;
+                       this.file = file;
+                       this.node = node;
+                       this.prop = prop;
+                       this.alt_code = alt_code;
                }
-                
-                
+               public bool eq(ValaCompileRequest c) {
+                       var neq = false;
+                       if (this.node == null && c.node == null) {
+                               neq = true;
+                       } else if (this.node == null || c.node == null) {
+                               neq = false;
+                       } else {
+                               neq = this.node.oid == c.node.oid ;
+                       }
+                       
+                       var peq = false;                        
+                       if (this.prop == null && c.prop == null) {
+                               peq = true;
+                       } else if (this.prop == null || c.prop == null) {
+                               peq = false;
+                       } else {
+                               peq = this.prop.name == c.prop.name ;
+                       }
+
+                       
+                       return 
+                               this.requestType == c.requestType &&
+                               this.file.path == c.file.path &&
+                               neq && peq &&
+                               this.alt_code == c.alt_code;
+                               
+                               
                
-                 
+               }
+               public string target()
+               {
+                       var pr = (Project.Gtk) this.file.project;
+                       return pr.firstBuildModuleWith(this.file);
+               
+               }
                
-               public async bool run()
+               string generateTempContents() {
+               
+                       var oldcode  = "";
+                       var contents = this.alt_code;
+                       if (this.requestType == ValaCompileRequestType.PROP_CHANGE) {
+                               oldcode  = this.prop.val;
+                               this.prop.val = this.alt_code;
+                               contents = this.file.toSourceCode();
+                               this.prop.val = oldcode;
+                       }
+                       return contents;
+               }
+               
+               
+               bool generateTempFile() {
+                
+                       var contents = this.generateTempContents();
+                        
+                       var pr = this.file.project;
+                       
+                       this.tmpfile = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
+                       try {
+                               GLib.FileUtils.set_contents(this.tmpfile,contents);
+                       } catch (GLib.FileError e) {
+                               GLib.debug("Error creating temp build file %s : %s", tmpfile, e.message);
+                               return false;
+                       }
+                       return true;
+               }
+               
+               public bool run()
                {
                        //this.queue = queue;
-
-                       if ( this.target == "") {
+                       if ( this.target() == "") {
                                GLib.debug("missing target");
-                               
+                               this.onCompileFail();
 
                                return false;
                        }
-                       BuilderApplication.showSpinner("spinner", "running meson");
+                       string[] args = {};
+                       args += BuilderApplication._self;
+                       if (this.requestType != ValaCompileRequestType.RUN) {
+                               args += "--skip-linking";
+                       }
+                       args += "--project";
+                       args += this.file.project.path;
+                       args += "--target";
+                       args +=  this.target();
+                       if  (this.requestType == ValaCompileRequestType.PROP_CHANGE || this.requestType == ValaCompileRequestType.FILE_CHANGE) {
+                               
+                               if (!this.generateTempFile()) {
+                                       GLib.debug("failed to make temp file");
+                                       this.onCompileFail();
+                                       return false;
+                               }
+                               args += "--add-file";
+                               args +=  this.tmpfile;
+                               args += "--skip-file";
+                               args += this.file.targetName(); // ?? bjs???
+                       }
+                       var pr = (Project.Gtk)(file.project);
+                       try {
+                               pr.makeProjectSubdir("build");
+                               this.compiler = new Spawn(pr.path + "/build", args);
+                       } catch (GLib.Error e) {
+                               GLib.debug("Spawn failed: %s", e.message);
 
-                       var res = yield  this.runMeson();
-       
-                       if (0 != res) {
-                               GLib.debug("Failed to run Meson");
-                               BuilderApplication.showSpinner("");
+                               this.onCompileFail();
                                return false;
                        }
-                       BuilderApplication.showSpinner("spinner", "running ninja");
-                       res = yield this.runNinja();
-                       if (0 != res) {
-                               GLib.debug("Failed to run ninja");
+                   this.compiler.output_line.connect(this.onOutput);
+                       this.compiler.complete.connect(this.onCompileComplete);
+                       try {
+                               this.compiler.run(); 
+                       } catch (GLib.Error e) {
+                               GLib.debug("Spawn error %s", e.message);
+                               this.onCompileFail();
                                return false;
                        }
-                       
-                       BuilderApplication.showSpinner("");
-                       return this.execResult();
-                         
+                       return true; // it's running..
+               }
+               void onCompileFail() // only called before we start (assumes spinner has nto started etc..
+               {
+                       this.compiler = null;
+                       this.deleteTemp();
                }
                
-               async int runMeson() {
-                       if (GLib.FileUtils.test(this.project.path + "/build", GLib.FileTest.EXISTS)) {
-                               return 0; //assume it's been set up.
-                       }
-                       string[] args = { "/usr/bin/meson" ,"setup","build", "--prefix=/" };            
-
-                       this.spawn = new Spawn(this.project.path , args);
-                       this.spawn.output_line.connect(( str) => {
-                               this.onOutput(str);
-                       });
-                       var res = yield this.spawn.run_async();
-                       return res;
+               public void cancel() {
+                       Posix.kill(this.compiler.pid, 9);
+                       this.compiler = null;
+                       this.deleteTemp();
                }
-                       
-               async int runNinja() 
+               
+               public void deleteTemp()
                {
-                       if (!GLib.FileUtils.test(this.project.path + "/build", GLib.FileTest.EXISTS)) {
-                               GLib.debug("build is missing");
-                               return -1; //assume it's been set up.
+                        if (this.tmpfile == "") {
+                               return;
+                       }
+                       if (GLib.FileUtils.test(this.tmpfile, GLib.FileTest.EXISTS)) {
+                               GLib.FileUtils.unlink(this.tmpfile);
                        }
-                       string[] args = { "/usr/bin/ninja"};            
+                       var cf = this.tmpfile.substring(0, this.tmpfile.length-4) + "c";
+                       GLib.debug("try remove %s",cf);
+                       if (GLib.FileUtils.test(cf, GLib.FileTest.EXISTS)) {
+                               GLib.FileUtils.unlink(cf);
+                       }
+                       var ccf = GLib.Path.get_dirname(cf) + "/build/" + GLib.Path.get_basename(cf);
+                       GLib.debug("try remove %s",ccf);
+                       if (GLib.FileUtils.test(ccf, GLib.FileTest.EXISTS)) {
+                               GLib.FileUtils.unlink(ccf);
+                       }
+                       this.tmpfile = "";
+               }
+               public void onCompileComplete(int res, string output, string stderr) 
+               {
+                       this.deleteTemp();
+                       this.compiler.isZombie();
+                       GLib.debug("compile got %s", output);
+                       if (output == "") {
+                               BuilderApplication.showSpinner(false);
+                               return;
+                       }
+                       
+                       try { 
+                               //GLib.debug("GOT output %s", output);
+                               
+                               var pa = new Json.Parser();
+                               pa.load_from_data(output);
+                               var node = pa.get_root();
 
-                       this.spawn = new Spawn(this.project.path + "/build" , args);
-                       this.spawn.output_line.connect(( str) => {
-                               this.onOutput(str);
-                       });
-                        var res = yield this.spawn.run_async();
-                       return res;
-                       
-               }       
-               public void cancel() {
-                       if (this.spawn != null && this.spawn.pid > 0) {
-                               Posix.kill(this.spawn.pid, 9);
+                               if (node.get_node_type () != Json.NodeType.OBJECT) {
+                                       BuilderApplication.showSpinner(false);
+                                       return;
+                               }
+                               var ret = node.get_object ();   
+                               //CompileError.parseCompileResults(this,ret);
+                               BuilderApplication.showSpinner(false);
+                               
+                       
+                               
+                               
+                               
+                       } catch (GLib.Error e) {
+                               GLib.debug("parsing output got error %s", e.message);
+                               BuilderApplication.showSpinner(false);
+                               return;
+                               
                        }
-                       this.spawn = null;
-               
-               }       
-                        
+                       if (this.requestType == ValaCompileRequestType.RUN) {
+                               this.execResult();
+                       }
+               }
                 
-               /*
-                 
+               public void onOutput(string line)
+               {
+                       // pass it to UI?
+                       
+               }
                public int totalErrors(string type, JsRender.JsRender? file=null) 
                {
                        var ar = this.errorByType.get(type);
@@ -127,10 +261,26 @@ namespace Palete {
                        }
                        return ret;
                }
-               */
-               
                
+               public void runJavascript( )
+               {
+                       //this.queue = queue;
+                
+                       var contents = this.alt_code == "" ? this.file.toSourceCode() : this.generateTempContents();
+                       
+                       Javascript.singleton().validate(contents, this.file );
+                       
+                       
+                        
+                       BuilderApplication.showSpinner(false);
+                       BuilderApplication.updateCompileResults();
+                       
+                       //this.queue.onCompileComplete(this);
+                               
+                        
+                 // see pack file (from palete/palete..palete_palete_javascriptHasCompressionErrors.)
                  
+               }
                public void killChildren(int pid)
                {
                        if (pid < 1) {
@@ -139,7 +289,7 @@ namespace Palete {
                        var cn = "/proc/%d/task/%d/children".printf(pid,pid);
                        if (!FileUtils.test(cn, GLib.FileTest.EXISTS)) {
                                GLib.debug("%s doesnt exist - killing %d", cn, pid);
-                                Posix.kill(pid, 9);
+                               Posix.kill(pid, 9);
                                return;
                        }
                        string cpids = "";
@@ -155,36 +305,36 @@ namespace Palete {
                                // skip
                        }
                        GLib.debug("killing %d", pid);  
-                       //Posix.kill(pid, 9);
+                       Posix.kill(pid, 9);
                }
                
-               public int terminal_pid = 0;
-               public bool execResult()
+               int terminal_pid = 0;
+               public void execResult()
                {
                                
                        this.killChildren(this.terminal_pid);
                        this.terminal_pid = 0;
                          
-                       var exe = this.target;
-                       var pr = (Project.Gtk) this.project;
+                       var exe = this.target();
+                       var pr = (Project.Gtk) this.file.project;
                        var cg =  pr.compilegroups.get(exe);
                        
-                       var exbin = pr.path + "/build/" + exe;
-                       if (!GLib.FileUtils.test(exbin, GLib.FileTest.EXISTS)) {
-                               GLib.debug("Missing output file: %s\n",exbin);
-                               return false;
+                       if (!GLib.FileUtils.test(exe, GLib.FileTest.EXISTS)) {
+                               print("Missing output file: %s\n",exe);
+                               return;
                        }
-                       var gdb_cfg = pr.path + "/build/.gdb-script";
+                       var gdb_cfg= pr.path + "/build/.gdb-script";
                        if (!GLib.FileUtils.test(gdb_cfg, GLib.FileTest.EXISTS)) {
                                pr.writeFile("build/.gdb-script", "set debuginfod enabled off\nr");
                        }
-                        
+                       
+                       
                        
                        string[] args = "/usr/bin/gnome-terminal --disable-factory --wait -- /usr/bin/gdb -x".split(" ");
 
                        args+= gdb_cfg;
  
-                       args += exbin;
+                       args += exe;
                        if (cg.execute_args.length > 0) {
                                args+= "--args";
                                var aa = cg.execute_args.split(" ");
@@ -211,9 +361,8 @@ namespace Palete {
                                
                    } catch(GLib.Error e) {
                                GLib.debug("Failed to spawn: %s", e.message);
-                               return false;
+                               return;
                        }
-                       return true;
                        
                }