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