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