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