Fix #5829 - Messing around with flutter API
[roobuilder] / src / Palete / Palete.vala
1
2 using Gtk;
3 namespace Palete 
4 {
5
6
7         public errordomain Error {
8                 INVALID_TYPE,
9                 NEED_IMPLEMENTING,
10                 MISSING_FILE,
11                 INVALID_VALUE
12         }
13
14         public class Usage : Object 
15         {
16                 public Gee.ArrayList<string> left;
17                 public Gee.ArrayList<string> right;
18                 public Usage(Gee.ArrayList<string> ileft, Gee.ArrayList<string> iright)
19                 {
20                         this.left = ileft;
21                         this.right=  iright;
22                 }
23                 public bool leftHas(string s)
24                 {
25                         for(var i = 0 ; i < this.left.size; i++) {
26                                 var m = this.left.get(i);
27                                 if (s == m) {
28                                         return true;
29                                 }
30                                 if (!m.contains(":")) {
31                                         continue;
32                                 }
33                                 var ar = m.split(":");
34                                 if (ar[0] == s) {
35                                         return true;
36                                 }
37                         }
38                         return false;
39                                 
40                 }
41
42                 
43         }
44
45         
46
47    //static Gee.HashMap<string,Palete>? cache = null;
48     
49     /*
50     public static Palete factory(project)
51     {
52         if (cache == null) {
53             cache = new Gee.HashMap<string,Palete>();
54         }
55         if (cache.get(xtype) != null) {
56             return cache.get(xtype);
57         }
58         switch(xtype) {
59             case "Gtk":
60                 cache.set(xtype, new Gtk());
61                 break;
62             case "Roo":
63                 cache.set(xtype, new Roo());
64                 break;
65             default:
66                 throw new Error.INVALID_TYPE("invalid argument to Palete factory");
67         }
68         return cache.get(xtype);
69     }
70      */ 
71
72     public abstract class Palete : Object 
73     {
74         
75        
76         public string name;
77
78                 public Gee.ArrayList<Usage> map;
79
80                 public Gee.HashMap<string,GirObject> classes; // used in roo.. 
81                 
82                 public Project.Project project;
83         
84         public Palete(Project.Project project)
85         {
86                                 // nothing?
87                         this.project = project;
88                         this.map = null;
89                         this.classes = null;
90         }
91         
92         
93         //map : false, // array of mappings   left: [] , right : []
94         
95         //items : false, // the tree of nodes.
96         
97         
98
99
100         string  guessName(JsRender.Node ar) throws Error // turns the object into full name.
101         {
102             throw new Error.NEED_IMPLEMENTING("xxx. guessName needs implimenting");
103         }
104             
105
106             
107          
108                 // this is the old verison using 'Usage'... see flutter for a better version..
109             
110                 public string[] original_getChildList(string in_rval)
111         {
112
113                         if (this.map == null) {
114                                 this.load();
115                         }
116                         // empty == *top
117                         
118                         var rval = in_rval == "" ? "*top" : in_rval; 
119                                         
120                                         // should be a bit more than this..
121                                 // -> it should look for all elements that inherit 
122                                 string[] ret = {};
123                         var rt = new Gee.ArrayList<string>();
124                         for (var i = 0; i < this.map.size; i++) {
125                                 var m = this.map.get(i);
126                                         
127                                         if (!m.leftHas(rval)) {
128                                         continue;
129                                 }
130                                 print("found LEFT, adding right\n");
131                         
132                                 for(var ii =0; ii < m.right.size; ii++) {
133                                                 var l = m.right.get(ii);
134                                                 
135                                                 if (rt.index_of(l) > -1) {
136                                                         continue;
137                                                 }
138                                         //print("ADD " + string.joinv(", ", ret) + "\n");
139                                                 ret += l;
140                                         rt.add(l);
141                                         }
142                                         
143                                         
144                                 }
145                         print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
146                         //console.log("DROP LIST:");
147                         //console.dump(ret);
148                         return ret;
149                                 
150         }
151
152             
153             
154         public string[] default_getDropList(string rval)
155         {
156
157                         if (this.map == null) {
158                                 this.load();
159                         }
160
161                                         
162                                         // should be a bit more than this..
163                                 // -> it should look for all elements that inherit 
164                                 string[] ret = {};
165                         var rt = new Gee.ArrayList<string>();
166                         for (var i = 0; i < this.map.size; i++) {
167                                 var m = this.map.get(i);
168                                         
169                                         if (m.right.index_of(rval) < 0) {
170                                         continue;
171                                 }
172                                 //print("found RIGHT, adding left\n");
173                         
174                                 for(var ii =0; ii < m.left.size; ii++) {
175                                                 var l = m.left.get(ii);
176                                                 
177                                                 if (rt.index_of(l) > -1) {
178                                                         continue;
179                                                 }
180                                         //print("ADD " + string.joinv(", ", ret) + "\n");
181                                                 ret += l;
182                                         rt.add(l);
183                                         }
184                                         
185                                         
186                                 }
187                          print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
188                         //console.log("DROP LIST:");
189                         //console.dump(ret);
190                         return ret;
191             
192         }
193       
194         public void saveTemplate (string name, JsRender.Node data)
195         {
196
197                         var gn = data.fqn();
198             // store it in user's directory..
199             var appdir =  GLib.Environment.get_home_dir() + "/.Builder"; 
200
201                         
202             if (!GLib.FileUtils.test(appdir+ "/" + gn, GLib.FileTest.IS_DIR)) {
203                                 GLib.File.new_for_path (appdir+ "/" + gn).make_directory ();
204                                 
205             }
206             GLib.FileUtils.set_contents(appdir+ "/" + gn + "/" +  name + ".json", data.toJsonString());
207             
208         }
209         
210         /**
211          * list templates - in home directory (and app dir in future...)
212          * @param {String} name  - eg. Gtk.Window..
213          * @return {Array} list of templates available..
214          */
215           
216         public  GLib.List<string> listTemplates (JsRender.Node node)
217         {
218             
219                         var gn = node.fqn();
220                                 
221                         var ret = new GLib.List<string>();
222                         var dir= GLib.Environment.get_home_dir() + "/.Builder/" + gn;
223                         if (!GLib.FileUtils.test(dir, GLib.FileTest.IS_DIR)) {
224                                 return ret;
225                         }
226                         
227
228
229                                     
230                         var f = File.new_for_path(dir);
231                         
232                                 var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
233                                  
234                                 FileInfo next_file; 
235                                 while ((next_file = file_enum.next_file(null)) != null) {
236                                         var n = next_file.get_display_name();
237                                         if (!Regex.match_simple ("\\.json$", n)) {
238                                                 continue;
239                                         }
240                                         ret.append( dir + "/" + n);
241                                 }
242                                 return ret;
243             
244                 }
245  
246         public JsRender.Node? loadTemplate(string path)
247         {
248
249                         var pa = new Json.Parser();
250                         pa.load_from_file(path);
251                         var node = pa.get_root();
252
253                         if (node.get_node_type () != Json.NodeType.OBJECT) {
254                                 return null;
255                         }
256                         var obj = node.get_object ();
257
258                         var ret = new JsRender.Node();
259
260
261                         ret.loadFromJson(obj, 1);
262                         ret.ref(); // not sure if needed -- but we had a case where ret became uninitialized?
263                 
264                         return ret;
265                 }
266
267
268
269                 public   void  loadUsageFile (string fname) {
270
271
272
273                         
274                                 print("Palete Load called\n");
275                         string raw;
276                         if (!FileUtils.test (fname, FileTest.EXISTS)) {
277                                 throw new Error.MISSING_FILE(fname + " not found");
278                         }
279         
280                         FileUtils.get_contents(fname, out raw);
281                       // print(data);
282                         var data  = raw.split("\n");
283                         var state = 0;
284                         var cfg = new Gee.ArrayList<Usage>();
285                         var left = new Gee.ArrayList<string>();
286                         var right = new Gee.ArrayList<string>();
287         
288                         for (var i = 0; i < data.length; i++) {
289                                 var d = data[i].strip();
290                                 //print("READ " + d + "\n");
291                                 if (
292                                         d.length < 1
293                                         ||
294                                          Regex.match_simple ("^\\s+$", d)
295                                         ||
296                                         Regex.match_simple ("^\\s*/", d)
297                                  ){
298                                         continue;
299                                 }
300                                 
301                                     if (Regex.match_simple ("^left:", d)) { 
302                                         state = 1;
303                                         if (left.size > 0 ){
304                                             cfg.add(new Usage( left, right));
305                                                         }
306                                         left = new Gee.ArrayList<string>();
307                                                 right = new Gee.ArrayList<string>();
308                                         continue;
309                                     }
310                                      if (Regex.match_simple ("^right:", d)) { 
311                                         state = 2;
312                                         continue;
313                                     }
314                                     if (state == 1) {
315                                                         //print("add left: " + d + "\n");
316                                         left.add(d);
317                                         continue;
318                                     }
319                                                 //print("add Right: " + d + "\n");
320                                     right.add(d);
321                                     //Seed.quit();
322                                    
323                         }
324                         if (left.size > 0 ){
325                                 cfg.add(new Usage( left, right));
326                         }
327                         this.map = cfg;
328
329            }
330
331          
332                 public   void validateVala(
333                                 WindowState state,
334                                 string code, 
335                                 string property, 
336                                 string ptype,
337                                 JsRender.JsRender file,
338                                 JsRender.Node node
339                  ) 
340                 {   
341
342                         print("validate code (%s) %s\n", file.language, code);
343                          
344                 
345                          
346                         if (file.language != "vala" ) { // not sure if we need to validate property
347                                 return;
348                         }
349                         // file.project , file.path, file.build_module, ""
350                         
351                 
352                          
353                         //var cd = new JSCore.ClassDefinitionEmpty();
354                         state.valasource.checkFileWithNodePropChange(
355                                         file,
356                                         node, 
357                                         property, 
358                                         ptype,
359                                         code
360                          );
361                          
362
363                 }
364                  
365         
366         
367         
368                 public   bool  javascriptHasErrors(
369                                         WindowState state,
370                                         string code, 
371                                         string property, 
372                                         string ptype,
373                                         JsRender.JsRender file, 
374                                         out Gee.HashMap<int,string> errors
375                                  ) 
376                 {   
377
378                          print("validate code (%s) ptype=%s property=%s\n", file.language, ptype, property);
379                         errors = new Gee.HashMap<int,string>();
380                 
381                         if (file.language != "js") {
382                                 return false;
383                          }
384                          if (ptype != "listener" && property.length > 0 && property[0] == '|') {
385                                 return false;
386                          }
387                         
388                         //var cd = new JSCore.ClassDefinitionEmpty();
389                         //print("TESTING CODE %s\n", code);
390                         string errmsg;
391                         var testcode = ptype == "file" ? code : "var __aaa___ = " + code;
392                         var line = Javascript.singleton().validate(
393                                                                   testcode, out errmsg);
394
395                         if (line > -1) {
396                                 if (ptype == "file") {
397                                         var err = new Json.Object();
398                                         err.set_int_member("ERR-TOTAL", 1);
399                                         var files_obj = new Json.Object();
400                                         var lines_obj = new Json.Object();
401                                         var lines_ar = new Json.Array();
402                                         lines_ar.add_string_element(errmsg);
403                                         lines_obj.set_array_member(line.to_string(), lines_ar);
404                                         files_obj.set_object_member(file.path, lines_obj);
405                                          
406                                         err.set_object_member("ERR", files_obj);
407  
408                                         state.showCompileResult(err);
409                                         // do not set errors.. that's not done here..
410                                         return true;
411                                 }
412                                 errors.set(line, errmsg); // depricated - this is used by the editor currently -- but we are planning to switch from that..
413                                 print("got  errors\n");
414                                 return true;
415
416                         }
417                         // now syntax is OK.. try the 
418                         
419                         
420                         
421                         if (ptype == "file") {
422                                  return this.javascriptHasCompressionErrors(file, state, code);
423                         }
424                         print("no errors\n");
425                         return false;
426                           
427                 } 
428                 
429                 public bool  javascriptHasCompressionErrors(JsRender.JsRender file, WindowState state, string code)
430                 {
431                         // this uses the roojspacker code to try and compress the code.
432                         // it should highlight errors before we actually push live the code.
433                         
434                         // standard error format:  file %s, line %s, Error 
435                         
436                         var cfg = new JSDOC.PackerRun();
437                         cfg.opt_keep_whitespace = false;
438                         cfg.opt_skip_scope = false;
439                         cfg.opt_dump_tokens = false;                    
440                         cfg.opt_clean_cache = false;
441                         
442
443                         var p = new JSDOC.Packer(cfg);
444                          
445                  
446                          
447                         p.packFile(code, file.path,"");
448                         state.showCompileResult(p.result);
449                         if (p.hasErrors("")) {
450                                 return true;
451                         }
452                         return false;
453                         
454
455                 
456                 }
457                 
458                 
459                       
460                 public abstract void fillPack(JsRender.Node node,JsRender.Node parent);
461                 public abstract void load();
462                 public abstract Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type);
463                 public abstract GirObject? getClass(string ename);
464         
465                 public abstract bool typeOptions(string fqn, string key, string type, out string[] opts);
466                 public abstract  List<SourceCompletionItem> suggestComplete(
467                                 JsRender.JsRender file,
468                                 JsRender.Node? node,
469                                 string proptype, 
470                                 string key,
471                                 string complete_string
472                 );
473                 public abstract string[] getChildList(string in_rval);
474                 public abstract string[] getDropList(string rval);              
475                 
476                 
477         }
478
479
480 }
481
482
483