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