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