2 // valac TreeBuilder.vala --pkg libvala-0.24 --pkg posix -o /tmp/treebuilder
6 public errordomain ValaSourceError {
10 public delegate void ValaSourceResult(Json.Object res);
12 public class ValaSourceReport : Vala.Report {
14 public string filepath;
16 public string tmpname;
18 //public Gee.ArrayList<ValaSourceNotice> notices;
19 public Json.Object result;
21 //public Gee.HashMap<int,string> line_errors;
23 public void compile_notice(string type, string filename, int line, string message) {
24 if (!this.result.has_member(type)) {
25 this.result.set_object_member(type, new Json.Object());
27 var t = this.result.get_object_member(type);
28 if (!t.has_member(filename)) {
29 t.set_object_member(filename, new Json.Object());
31 var tt = t.get_object_member(filename);
32 if (!tt.has_member(line.to_string())) {
33 tt.set_array_member(line.to_string(), new Json.Array());
35 var tl = tt.get_array_member(line.to_string());
36 tl.add_string_element(message);
42 public ValaSourceReport(string filepath, string tmpname)
45 this.filepath = filepath;
46 this.tmpname = tmpname;
47 this.result = new Json.Object();
48 this.result.set_boolean_member("success", true);
49 this.result.set_string_member("message", "");
53 //this.line_errors = new Gee.HashMap<int,string> ();
54 //this.notices = new Gee.ArrayList<ValaSourceNotice>();
57 public override void warn (Vala.SourceReference? source, string message) {
61 //stderr.printf ("My error: %s\n", message);
64 if (source.file.filename != this.tmpname) {
65 this.compile_notice("WARN", source.file.filename , source.begin.line, message);
68 this.compile_notice("WARN", this.filepath, source.begin.line, message);
71 public override void depr (Vala.SourceReference? source, string message) {
75 //stderr.printf ("My error: %s\n", message);
78 if (source.file.filename != this.tmpname) {
79 this.compile_notice("DEPR", source.file.filename, source.begin.line, message);
82 this.compile_notice("DEPR", this.filepath, source.begin.line, message);
86 public override void err (Vala.SourceReference? source, string message) {
90 //stderr.printf ("My error: %s\n", message);
92 if (source.file.filename != this.tmpname) {
93 this.compile_notice("ERR", source.file.filename, source.begin.line, message);
94 print ("Other file: Got error error: %d: %s\n", source.begin.line, message);
99 this.compile_notice("ERR", this.filepath, source.begin.line, message);
100 print ("Test file: Got error error: %d: %s\n", source.begin.line, message);
105 var iter = this.line_errors.map_iterator();
106 while (iter.next()) {
107 print ("%d : %s\n\n", iter.get_key(), iter.get_value());
114 public class ValaSource : Object {
116 public static void jerr(string str)
118 var ret = new Json.Object();
119 ret.set_boolean_member("success", false);
120 ret.set_string_member("message", str);
122 var generator = new Json.Generator ();
123 var root = new Json.Node(Json.NodeType.OBJECT);
124 root.init_object(ret);
125 generator.set_root (root);
127 generator.pretty = true;
128 generator.indent = 4;
131 print("%s\n", generator.to_data (null));
132 GLib.Process.exit(Posix.EXIT_FAILURE);
136 public static void buildApplication()
138 //print("build based on Application settings\n");
140 if (BuilderApplication.opt_compile_target == null) {
141 jerr("missing compile target --target");
144 Project.Project.loadAll();
145 var proj = Project.Project.getProjectByHash(BuilderApplication.opt_compile_project);
148 jerr("could not load test project %s".printf( BuilderApplication.opt_compile_project));
151 if (proj.xtype != "Gtk") {
152 jerr("%s is not a Gtk Project".printf( BuilderApplication.opt_compile_project));
154 var gproj = (Project.Gtk)proj;
157 if (!gproj.compilegroups.has_key(BuilderApplication.opt_compile_target)) {
158 jerr("missing compile target %s".printf(BuilderApplication.opt_compile_target));
161 if (BuilderApplication.opt_compile_skip != null) {
162 skip_file = BuilderApplication.opt_compile_skip;
165 if (BuilderApplication.opt_compile_add != null) {
166 add_file = BuilderApplication.opt_compile_add;
170 var vs = new ValaSource(gproj, add_file, BuilderApplication.opt_compile_target, skip_file);
176 Vala.CodeContext context;
177 ValaSourceReport report;
178 JsRender.JsRender file;
180 public string build_module;
181 public string filepath;
182 public string original_filepath;
184 // file.project , file.path, file.build_module, ""
185 public ValaSource(Project.Gtk project, string filepath, string build_module, string original_filepath) {
188 this.filepath = filepath;
189 this.build_module = build_module;
190 this.original_filepath = original_filepath;
191 this.project = project;
194 public void dumpCode(string str)
196 var ls = str.split("\n");
197 for (var i=0;i < ls.length; i++) {
198 print("%d : %s\n", i+1, ls[i]);
202 //public Gee.HashMap<int,string> checkFile()
204 // return this.checkString(JsRender.NodeToVala.mungeFile(this.file));
207 public Gee.HashMap<int,string> checkFileWithNodePropChange(
208 JsRender.JsRender file,
213 ValaSourceResult result_callback)
218 Gee.HashMap<int,string> ret = new Gee.HashMap<int,string> ();
219 var hash = ptype == "listener" ? node.listeners : node.props;
221 // untill we get a smarter renderer..
222 // we have some scenarios where changing the value does not work
223 if (prop == "* xns" || prop == "xtype") {
228 var old = hash.get(prop);
229 var newval = "/*--VALACHECK-START--*/ " + val ;
231 hash.set(prop, newval);
232 var tmpstring = JsRender.NodeToVala.mungeFile(file);
234 //print("%s\n", tmpstring);
235 var bits = tmpstring.split("/*--VALACHECK-START--*/");
237 if (bits.length > 0) {
238 offset = bits[0].split("\n").length +1;
240 //this.dumpCode(tmpstring);
241 //print("offset %d\n", offset);
242 this.checkStringSpawn(tmpstring, result_callback );
251 public void checkStringSpawn(
253 ValaSourceResult result_callback
256 FileIOStream iostream;
257 var tmpfile = File.new_tmp ("test-XXXXXX.vala", out iostream);
260 OutputStream ostream = iostream.output_stream;
261 DataOutputStream dostream = new DataOutputStream (ostream);
262 dostream.put_string (contents);
266 args += FileUtils.read_link("/proc/self/exe");
268 args += this.project.fn;
270 args += this.build_module;
271 args += "--add-file";
272 args += tmpfile.get_path();
273 args += "--skip-file";
274 args += this.filepath;
278 var compiler = new Spawn("/tmp", args);
280 compiler.run((res, output, stderr) => {
283 var pa = new Json.Parser();
284 pa.load_from_data(output);
285 var node = pa.get_root();
287 if (node.get_node_type () != Json.NodeType.OBJECT) {
288 throw new ValaSourceError.INVALID_FORMAT ("Unexpected element type %s", node.type_name ());
292 result_callback(node.get_object ());
296 var ret = new Json.Object();
297 ret.set_boolean_member("success", false);
298 ret.set_string_member("message", e.message);
299 result_callback(ret);
309 public void compile( )
312 var valac = "valac " ;
314 context = new Vala.CodeContext ();
315 Vala.CodeContext.push (context);
317 context.experimental = false;
318 context.experimental_non_null = false;
330 for (int i = 2; i <= ver; i += 2) {
331 context.add_define ("VALA_0_%d".printf (i));
340 var vapidirs = this.project.vapidirs();
341 // what's the current version of vala???
344 vapidirs += Path.get_dirname (context.get_vapi_path("glib-2.0")) ;
346 for(var i =0 ; i < vapidirs.length; i++) {
347 valac += " --vapidir=" + vapidirs[i];
351 // or context.get_vapi_path("glib-2.0"); // should return path..
352 context.vapi_directories = vapidirs;
353 context.report.enable_warnings = true;
354 context.metadata_directories = { };
355 context.gir_directories = {};
356 context.thread = true;
359 this.report = new ValaSourceReport(this.original_filepath, this.filepath);
360 context.report = this.report;
363 context.basedir = "/tmp"; //Posix.realpath (".");
365 context.directory = context.basedir;
368 // add default packages:
369 //if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
370 context.profile = Vala.Profile.GOBJECT;
372 var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
373 context.root.add_using_directive (ns_ref);
375 var source_file = new Vala.SourceFile (
377 Vala.SourceFileType.SOURCE,
381 source_file.add_using_directive (ns_ref);
382 context.add_source_file (source_file);
384 // add all the files (except the current one) - this.file.path
385 var pr = this.project;
386 if (this.file.build_module.length > 0) {
387 var cg = pr.compilegroups.get(this.build_module);
388 for (var i = 0; i < cg.sources.size; i++) {
389 var path = pr.resolve_path(
390 pr.resolve_path_combine_path(pr.firstPath(),cg.sources.get(i)));
392 if (!FileUtils.test(path, FileTest.EXISTS)) {
395 // skip thie original
396 if (path == this.original_filepath.replace(".bjs", ".vala")) {
400 if (FileUtils.test(path, FileTest.IS_DIR)) {
403 //print("Add source file %s\n", path);
407 if (Regex.match_simple("\\.c$", path)) {
408 context.add_c_source_file(path);
413 var xsf = new Vala.SourceFile (
415 Vala.SourceFileType.SOURCE,
418 xsf.add_using_directive (ns_ref);
419 context.add_source_file(xsf);
423 // default.. packages..
424 context.add_external_package ("glib-2.0");
425 context.add_external_package ("gobject-2.0");
426 // user defined ones..
428 var dcg = pr.compilegroups.get("_default_");
429 for (var i = 0; i < dcg.packages.size; i++) {
430 valac += " --pkg " + dcg.packages.get(i);
431 context.add_external_package (dcg.packages.get(i));
434 //Vala.Config.PACKAGE_SUFFIX.substring (1)
436 // add the modules...
440 //context.add_external_package ("libvala-0.24");
444 //add_documented_files (context, settings.source_files);
446 Vala.Parser parser = new Vala.Parser ();
447 parser.parse (context);
448 //gir_parser.parse (context);
449 if (context.report.get_errors () > 0) {
450 Vala.CodeContext.pop ();
451 Glib.debug("parse got errors");
452 //((ValaSourceReport)context.report).dump();
453 this.report.result.set_boolean_member("success", false);
454 this.report.result.set_string_member("message", "Parse failed");
464 if (context.report.get_errors () > 0) {
465 Vala.CodeContext.pop ();
466 Glib.debug("check got errors");
467 //((ValaSourceReport)context.report).dump();
468 this.report.result.set_boolean_member("success", false);
469 this.report.result.set_string_member("message", "Check failed");
475 //context.codegen = new Vala.GDBusServerModule ();
478 context.output = "/tmp/testbuild";
479 valac += " -o " +context.output;
480 //context.codegen.emit (context);
482 var ccompiler = new Vala.CCodeCompiler ();
483 var cc_command = Environment.get_variable ("CC");
484 var pkg_config_command = Environment.get_variable ("PKG_CONFIG");
486 ccompiler.compile (context, cc_command, new string[] { }, pkg_config_command);
488 ccompiler.compile (context, cc_command, new string[] { });
492 Vala.CodeContext.pop ();
496 public void outputResult()
498 var generator = new Json.Generator ();
499 generator.indent = 1;
500 generator.pretty = true;
501 var node = new Json.Node(Json.NodeType.OBJECT);
502 node.set_object(this.report.result);
504 generator.set_root(node);
506 generator.pretty = true;
507 generator.indent = 4;
510 print("%s\n", generator.to_data (null));
511 GLib.Process.exit(Posix.EXIT_SUCCESS);
518 public Gee.HashMap<int,string> checkString(string contents)
521 var valac = "valac " ;
523 context = new Vala.CodeContext ();
524 Vala.CodeContext.push (context);
526 context.experimental = false;
527 context.experimental_non_null = false;
539 for (int i = 2; i <= ver; i += 2) {
540 context.add_define ("VALA_0_%d".printf (i));
549 var vapidirs = ((Project.Gtk)this.file.project).vapidirs();
550 // what's the current version of vala???
553 vapidirs += Path.get_dirname (context.get_vapi_path("glib-2.0")) ;
555 for(var i =0 ; i < vapidirs.length; i++) {
556 valac += " --vapidir=" + vapidirs[i];
560 // or context.get_vapi_path("glib-2.0"); // should return path..
561 context.vapi_directories = vapidirs;
562 context.report.enable_warnings = true;
563 context.metadata_directories = { };
564 context.gir_directories = {};
565 context.thread = true;
568 this.report = new ValaSourceReport(this.file.path);
569 context.report = this.report;
572 context.basedir = "/tmp"; //Posix.realpath (".");
574 context.directory = context.basedir;
577 // add default packages:
578 //if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
579 context.profile = Vala.Profile.GOBJECT;
581 var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
582 context.root.add_using_directive (ns_ref);
584 var source_file = new Vala.SourceFile (
586 Vala.SourceFileType.SOURCE,
587 "~~~~~testfile.vala",
590 source_file.add_using_directive (ns_ref);
591 context.add_source_file (source_file);
593 // add all the files (except the current one) - this.file.path
594 var pr = ((Project.Gtk)this.file.project);
595 if (this.file.build_module.length > 0) {
596 var cg = pr.compilegroups.get(this.file.build_module);
597 for (var i = 0; i < cg.sources.size; i++) {
598 var path = pr.resolve_path(
599 pr.resolve_path_combine_path(pr.firstPath(),cg.sources.get(i)));
601 if (!FileUtils.test(path, FileTest.EXISTS)) {
605 if (path == this.file.path.replace(".bjs", ".vala")) {
609 if (FileUtils.test(path, FileTest.IS_DIR)) {
612 //print("Add source file %s\n", path);
616 if (Regex.match_simple("\\.c$", path)) {
617 context.add_c_source_file(path);
622 var xsf = new Vala.SourceFile (
624 Vala.SourceFileType.SOURCE,
627 xsf.add_using_directive (ns_ref);
628 context.add_source_file(xsf);
632 // default.. packages..
633 context.add_external_package ("glib-2.0");
634 context.add_external_package ("gobject-2.0");
635 // user defined ones..
637 var dcg = pr.compilegroups.get("_default_");
638 for (var i = 0; i < dcg.packages.size; i++) {
639 valac += " --pkg " + dcg.packages.get(i);
640 context.add_external_package (dcg.packages.get(i));
643 //Vala.Config.PACKAGE_SUFFIX.substring (1)
645 // add the modules...
649 //context.add_external_package ("libvala-0.24");
651 this.report.compile_notice("START", "", 0, "");
654 //add_documented_files (context, settings.source_files);
656 Vala.Parser parser = new Vala.Parser ();
657 parser.parse (context);
658 //gir_parser.parse (context);
659 if (context.report.get_errors () > 0) {
660 print("parse got errors");
661 ((ValaSourceReport)context.report).dump();
663 Vala.CodeContext.pop ();
664 this.report.compile_notice("END", "", 0, "");
665 return this.report.line_errors;
672 if (context.report.get_errors () > 0) {
673 print("check got errors");
674 ((ValaSourceReport)context.report).dump();
675 Vala.CodeContext.pop ();
676 this.report.compile_notice("END", "", 0, "");
677 return this.report.line_errors;
681 //context.codegen = new Vala.GDBusServerModule ();
684 context.output = "/tmp/testbuild";
685 valac += " -o " +context.output;
686 //context.codegen.emit (context);
688 //(new Vala.CodeNode()).get_error_types().clear();
689 //(new Vala.NullType()).get_type_arguments().clear();
690 (new Vala.NullType(null)).get_type_arguments().clear();
692 this.report.compile_notice("END", "", 0, "");
693 print("%s\n", valac);
695 return this.report.line_errors;
704 int main (string[] args) {
706 var a = new ValaSource(file);
707 a.create_valac_tree();