Fix #8028 - language server performance, fix warnings and critical errors
[roobuilder] / src / Palete / ValaCompileRequest.vala
1
2
3
4 namespace Palete {
5          
6                 
7         public class ValaCompileRequest  : Object
8         {
9                 Project.Gtk project;
10                 string target;
11                 Spawn? spawn = null;
12                 
13                 public signal void onOutput(string str);
14         
15                 public Gee.HashMap<string,GLib.ListStore>? errorByType = null;
16                 public Gee.HashMap<string,GLib.ListStore>? errorByFile  = null;
17                         
18         
19                 public ValaCompileRequest (
20                         Project.Gtk project,
21                         string target
22                          
23                 ) {
24                         this.project =   project;
25                         this.target = target;
26                 }
27                  
28                  
29                 
30                   
31                 
32                 public async bool run()
33                 {
34                         //this.queue = queue;
35
36                         if ( this.target == "") {
37                                 GLib.debug("missing target");
38                                 
39
40                                 return false;
41                         }
42                         BuilderApplication.showSpinner("spinner", "running meson");
43
44                         var res = yield  this.runMeson();
45         
46                         if (0 != res) {
47                                 GLib.debug("Failed to run Meson");
48                                 BuilderApplication.showSpinner("");
49                                 return false;
50                         }
51                         BuilderApplication.showSpinner("spinner", "running ninja");
52                         res = yield this.runNinja();
53                         if (0 != res) {
54                                 GLib.debug("Failed to run ninja");
55                                 return false;
56                         }
57                         
58                         BuilderApplication.showSpinner("");
59                         return this.execResult();
60                           
61                 }
62                 
63                 async int runMeson() {
64                         if (GLib.FileUtils.test(this.project.path + "/build/meson-info", GLib.FileTest.EXISTS)) {
65                                 return 0; //assume it's been set up.
66                         }
67                         var exe = GLib.Environment.find_program_in_path( "meson");
68                         string[] args = { exe ,"setup", "build", "--prefix=/usr" };             
69                         GLib.debug("running meson");
70                         try {
71                                 this.spawn = new Spawn(this.project.path , args);
72                         } catch (GLib.Error e) {
73                                 return -1;
74                         }
75                         this.spawn.output_line.connect(( str) => {
76                                 this.onOutput(str);
77                         });
78                         var res = yield this.spawn.run_async();
79                         return res;
80                 }
81                         
82                 async int runNinja() 
83                 {
84                         if (!GLib.FileUtils.test(this.project.path + "/build", GLib.FileTest.EXISTS)) {
85                                 GLib.debug("build is missing");
86                                 return -1; //assume it's been set up.
87                         }
88                         var exe = GLib.Environment.find_program_in_path( "ninja");
89                         string[] args = { exe };                
90                         try {
91                                 this.spawn = new Spawn(this.project.path + "/build" , args);
92                         } catch (GLib.Error e) {
93                                 return -1;
94                         }
95                         this.spawn.output_line.connect(( str) => {
96                                 this.onOutput(str);
97                         });
98                          var res = yield this.spawn.run_async();
99                         return res;
100                         
101                 }       
102                 public void cancel() {
103                         if (this.spawn != null && this.spawn.pid > 0) {
104                                 Posix.kill(this.spawn.pid, 9);
105                         }
106                         this.spawn = null;
107                 
108                 }       
109                          
110                  
111                 /*
112                   
113                 public int totalErrors(string type, JsRender.JsRender? file=null) 
114                 {
115                         var ar = this.errorByType.get(type);
116                         if (ar == null) {
117                                 GLib.debug("by type has no eroros %s", type);
118                                 return 0;
119                         }
120                         
121                         
122                         var ret =0;
123                         
124                         for(var i =0 ;i< ar.get_n_items();i++) {
125                                 var ce = (CompileError) ar.get_item(i);
126                                 if (file == null) {
127                                         ret += (int)ce.lines.get_n_items();
128                                         GLib.debug("got lines type has no eroros %s", type);
129                                         continue;
130                                 }
131                                 
132                                 
133                                 if (ce.file.path == file.path) {
134                                         ret += (int)ce.lines.get_n_items();
135                                 }
136                         }
137                         return ret;
138                 }
139                 */
140                 
141                 
142                   
143                 public void killChildren(int pid)
144                 {
145                         if (pid < 1) {
146                                 return;
147                         }
148                         var cn = "/proc/%d/task/%d/children".printf(pid,pid);
149                         if (!FileUtils.test(cn, GLib.FileTest.EXISTS)) {
150                                 GLib.debug("%s doesnt exist - killing %d", cn, pid);
151                                  Posix.kill(pid, 9);
152                                 return;
153                         }
154                         string cpids = "";
155                         try {
156                                 FileUtils.get_contents(cn, out cpids);
157                         
158
159                                 if (cpids.length > 0) {
160                                         this.killChildren(int.parse(cpids));
161                                 }
162
163                         } catch (GLib.FileError e) {
164                                 // skip
165                         }
166                         GLib.debug("killing %d", pid);  
167                         //Posix.kill(pid, 9);
168                 }
169                 
170                 public int terminal_pid = 0;
171                 public bool execResult()
172                 {
173                                 
174                         this.killChildren(this.terminal_pid);
175                         this.terminal_pid = 0;
176                           
177                         var exe = this.target;
178                         var pr = (Project.Gtk) this.project;
179                         var cg =  pr.compilegroups.get(exe);
180                         
181                         var exbin = pr.path + "/build/" + exe;
182                         if (!GLib.FileUtils.test(exbin, GLib.FileTest.EXISTS)) {
183                                 GLib.debug("Missing output file: %s\n",exbin);
184                                 return false;
185                         }
186                         var gdb_cfg = pr.path + "/build/.gdb-script";
187                         if (!GLib.FileUtils.test(gdb_cfg, GLib.FileTest.EXISTS)) {
188                                 pr.writeFile("build/.gdb-script", "set debuginfod enabled off\nr");
189                         }
190                         var gdb = GLib.Environment.find_program_in_path( "gdb"); 
191                         var term = GLib.Environment.find_program_in_path( "gnome-terminal"); 
192                         
193                         string[] args = @"$term --disable-factory --wait -- $gdb -x".split(" ");
194
195                         args+= gdb_cfg;
196  
197                         args += exbin;
198                         if (cg.execute_args.length > 0) {
199                                 args+= "--args";
200                                 var aa = cg.execute_args.split(" ");
201                                 for (var i =0; i < aa.length; i++) {
202                                         args += aa[i];
203                                 }
204                         }
205
206                   
207                     
208                     // should be home directory...
209                     
210                     
211                     try {
212                     
213                         var exec = new Spawn(pr.path , args);
214                         exec.env = GLib.Environ.get();
215                          
216                         exec.detach = true;
217                                 exec.run(); 
218
219                                 this.terminal_pid = exec.pid;
220                                 GLib.debug("Child PID = %d", this.terminal_pid);
221                                 
222                     } catch(GLib.Error e) {
223                                 GLib.debug("Failed to spawn: %s", e.message);
224                                 return false;
225                         }
226                         return true;
227                         
228                 }
229                 
230         } 
231                 
232                 
233                 
234 }
235
236