3a5a562d64c395045de25982f5a843f9535fab03
[roobuilder] / src / Palete / ValaCompileRequest.vala
1
2
3
4 namespace Palete {
5         public enum ValaCompileRequestType {
6                 PROP_CHANGE,
7                 FILE_CHANGE,
8                 PROJECT,
9                 RUN
10         }
11                 
12         public class ValaCompileRequest : Object
13         {
14                 ValaCompileRequestType requestType;
15                 
16                 public JsRender.JsRender? file = null;
17                 JsRender.Node? node = null;
18                 JsRender.NodeProp? prop = null;
19                 string alt_code = "";
20                 string tmpfile = "";
21                 Spawn? compiler  = null;
22                 ValaCompileQueue? queue = null;
23  
24                 
25         
26                 public Gee.HashMap<string,GLib.ListStore>? errorByType = null;
27                 public Gee.HashMap<string,GLib.ListStore>? errorByFile  = null;
28                         
29         
30                 public ValaCompileRequest(
31                         ValaCompileRequestType requestType,
32                         JsRender.JsRender file ,
33                         JsRender.Node? node,
34                         JsRender.NodeProp? prop,
35                         string alt_code = ""
36                          
37                 ) {
38                         this.requestType = requestType;
39                         this.file = file;
40                         this.node = node;
41                         this.prop = prop;
42                         this.alt_code = alt_code;
43                 }
44                 public bool eq(ValaCompileRequest c) {
45                         var neq = false;
46                         if (this.node == null && c.node == null) {
47                                 neq = true;
48                         } else if (this.node == null || c.node == null) {
49                                 neq = false;
50                         } else {
51                                 neq = this.node.oid == c.node.oid ;
52                         }
53                         
54                         var peq = false;                        
55                         if (this.prop == null && c.prop == null) {
56                                 peq = true;
57                         } else if (this.prop == null || c.prop == null) {
58                                 peq = false;
59                         } else {
60                                 peq = this.prop.name == c.prop.name ;
61                         }
62
63                         
64                         return 
65                                 this.requestType == c.requestType &&
66                                 this.file.path == c.file.path &&
67                                 neq && peq &&
68                                 this.alt_code == c.alt_code;
69                                 
70                                 
71                 
72                 }
73                 public string target()
74                 {
75                         var pr = (Project.Gtk) this.file.project;
76                         return pr.firstBuildModuleWith(this.file);
77                 
78                 }
79                 
80                 string generateTempContents() {
81                 
82                         var oldcode  = "";
83                         var contents = this.alt_code;
84                         if (this.requestType == ValaCompileRequestType.PROP_CHANGE) {
85                                 oldcode  = this.prop.val;
86                                 this.prop.val = this.alt_code;
87                                 contents = this.file.toSourceCode();
88                                 this.prop.val = oldcode;
89                         }
90                         return contents;
91                 }
92                 
93                 
94                 bool generateTempFile() {
95                  
96                         var contents = this.generateTempContents();
97                          
98                         var pr = this.file.project;
99                         
100                         this.tmpfile = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
101                         try {
102                                 GLib.FileUtils.set_contents(this.tmpfile,contents);
103                         } catch (GLib.FileError e) {
104                                 GLib.debug("Error creating temp build file %s : %s", tmpfile, e.message);
105                                 return false;
106                         }
107                         return true;
108                 }
109                 
110                 public bool run(ValaCompileQueue queue)
111                 {
112                         this.queue = queue;
113                         if ( this.target() == "") {
114                                 GLib.debug("missing target");
115                                 this.onCompileFail();
116
117                                 return false;
118                         }
119                         string[] args = {};
120                         args += BuilderApplication._self;
121                         if (this.requestType != ValaCompileRequestType.RUN) {
122                                 args += "--skip-linking";
123                         }
124                         args += "--project";
125                         args += this.file.project.path;
126                         args += "--target";
127                         args +=  this.target();
128                         if  (this.requestType == ValaCompileRequestType.PROP_CHANGE || this.requestType == ValaCompileRequestType.FILE_CHANGE) {
129                                 
130                                 if (!this.generateTempFile()) {
131                                         GLib.debug("failed to make temp file");
132                                         this.onCompileFail();
133                                         return false;
134                                 }
135                                 args += "--add-file";
136                                 args +=  this.tmpfile;
137                                 args += "--skip-file";
138                                 args += this.file.targetName(); // ?? bjs???
139                         }
140                         var pr = (Project.Gtk)(file.project);
141                         try {
142                                 pr.makeProjectSubdir("build");
143                                 this.compiler = new Spawn(pr.path + "/build", args);
144                         } catch (GLib.Error e) {
145                                 GLib.debug("Spawn failed: %s", e.message);
146
147                                 this.onCompileFail();
148                                 return false;
149                         }
150                     this.compiler.output_line.connect(this.onOutput);
151                         this.compiler.complete.connect(this.onCompileComplete);
152                         try {
153                                 this.compiler.run(); 
154                         } catch (GLib.Error e) {
155                                 GLib.debug("Spawn error %s", e.message);
156                                 this.onCompileFail();
157                                 return false;
158                         }
159                         return true; // it's running..
160                 }
161                 void onCompileFail() // only called before we start (assumes spinner has nto started etc..
162                 {
163                         this.compiler = null;
164                         this.deleteTemp();
165                 }
166                 
167                 public void cancel() {
168                         Posix.kill(this.compiler.pid, 9);
169                         this.compiler = null;
170                         this.deleteTemp();
171                 }
172                 
173                 public void deleteTemp()
174                 {
175                          if (this.tmpfile == "") {
176                                 return;
177                         }
178                         if (GLib.FileUtils.test(this.tmpfile, GLib.FileTest.EXISTS)) {
179                                 GLib.FileUtils.unlink(this.tmpfile);
180                         }
181                         var cf = this.tmpfile.substring(0, this.tmpfile.length-4) + "c";
182                         GLib.debug("try remove %s",cf);
183                         if (GLib.FileUtils.test(cf, GLib.FileTest.EXISTS)) {
184                                 GLib.FileUtils.unlink(cf);
185                         }
186                         var ccf = GLib.Path.get_dirname(cf) + "/build/" + GLib.Path.get_basename(cf);
187                         GLib.debug("try remove %s",ccf);
188                         if (GLib.FileUtils.test(ccf, GLib.FileTest.EXISTS)) {
189                                 GLib.FileUtils.unlink(ccf);
190                         }
191                         this.tmpfile = "";
192                 }
193                 public void onCompileComplete(int res, string output, string stderr) 
194                 {
195                         this.deleteTemp();
196                         this.compiler.isZombie();
197                         GLib.debug("compile got %s", output);
198                         if (output == "") {
199                                 this.queue.onCompileFail();
200                                 return;
201                         }
202                         
203                         try { 
204                                 //GLib.debug("GOT output %s", output);
205                                 
206                                 var pa = new Json.Parser();
207                                 pa.load_from_data(output);
208                                 var node = pa.get_root();
209
210                                 if (node.get_node_type () != Json.NodeType.OBJECT) {
211                                         this.queue.onCompileFail();
212                                         return;
213                                 }
214                                 var ret = node.get_object ();   
215                                 CompileError.parseCompileResults(this,ret);
216                                 this.queue.onCompileComplete(this);
217                                 
218                         
219                                 
220                                 
221                                 
222                         } catch (GLib.Error e) {
223                                 GLib.debug("parsing output got error %s", e.message);
224                                 this.queue.onCompileFail();
225                                 return;
226                                 
227                         }
228                         if (this.requestType == ValaCompileRequestType.RUN) {
229                                 this.queue.execResult(this);
230                         }
231                 }
232                  
233                 public void onOutput(string line)
234                 {
235                         // pass it to UI?
236                         
237                 }
238                 public int totalErrors(string type, JsRender.JsRender? file=null) 
239                 {
240                         var ar = this.errorByType.get(type);
241                         if (ar == null) {
242                                 GLib.debug("by type has no eroros %s", type);
243                                 return 0;
244                         }
245                         
246                         
247                         var ret =0;
248                         
249                         for(var i =0 ;i< ar.get_n_items();i++) {
250                                 var ce = (CompileError) ar.get_item(i);
251                                 if (file == null) {
252                                         ret += (int)ce.lines.get_n_items();
253                                         GLib.debug("got lines type has no eroros %s", type);
254                                         continue;
255                                 }
256                                 
257                                 
258                                 if (ce.file.path == file.path) {
259                                         ret += (int)ce.lines.get_n_items();
260                                 }
261                         }
262                         return ret;
263                 }
264                 
265                 public void runJavascript(ValaCompileQueue queue)
266                 {
267                         this.queue = queue;
268                  
269                         var contents = this.alt_code == "" ? this.file.toSourceCode() : this.generateTempContents();
270                         
271                         var ret = Javascript.singleton().validate(contents, this.file.targetName());
272                  
273                         CompileError.parseCompileResults(this,ret);
274                         this.queue.onCompileComplete(this);
275                                 
276                          
277                   // see pack file (from palete/palete..palete_palete_javascriptHasCompressionErrors.)
278                   
279                 }
280                 
281         } 
282                 
283                 
284                 
285 }
286
287