src/Palete/Roo.vala
[app.Builder.js] / src / Palete / Roo.vala
1 using Gtk;
2
3 namespace Palete {
4
5         
6 /*      
7         
8         
9     public class Introspect.El : Object
10     {
11         public enum eltype { 
12             NS,
13             CLASS,
14             METHOD,
15             PROP
16         }
17                 
18             
19         public eltype type;
20     }
21
22 */
23     public class Roo : Palete {
24                 
25                 
26         public Roo()
27         {
28
29
30             
31             base();
32             this.name = "Roo";
33                           
34         }
35
36                 Gee.HashMap<string,GirObject> propsFromJSONArray(string type, Json.Array ar)
37                 {
38
39                         var ret = new Gee.HashMap<string,GirObject>();
40                         
41                         for (var i =0 ; i < ar.get_length(); i++) {
42                                 var o = ar.get_object_element(i);
43                                 var name = o.get_string_member("name"); 
44                                 var prop = new GirObject(type, name );  
45                                  
46                                 prop.type        = o.get_string_member("type");
47                                 prop.doctxt  = o.get_string_member("desc");
48                                 prop.propertyof = o.has_member("memberOf") ? o.get_string_member("memberOf") : "";
49                                 prop.sig = o.has_member("sig") ? o.get_string_member("sig") : "";
50                                 
51                                 if (o.has_member("optvals")  ) {
52                                         var oar = o.get_array_member("optvals");
53                                         
54                                         for (var oi = 0; oi < oar.get_length(); oi++) {
55                                                 prop.optvalues.add(oar.get_string_element(oi));
56                                         }
57                                         
58                                 }       
59                                 
60                                 
61                                 
62                                 //print(type + ":" + name +"\n");
63                                 ret.set(name,prop);
64                         }
65                         return ret;
66                 }
67          
68                 public override void  load () {
69
70                         if (this.classes != null) {
71                                 return;
72                         }
73                         this.loadUsageFile(BuilderApplication.configDirectory() + "/resources/RooUsage.txt");
74                         this.classes = new Gee.HashMap<string,GirObject>();
75
76                                 
77                         var pa = new Json.Parser();
78                         pa.load_from_file(BuilderApplication.configDirectory() + "/resources/roodata.json");
79                         var node = pa.get_root();
80
81                         var clist =  node.get_object().get_object_member("data");
82                                 clist.foreach_member((o , key, value) => {
83                                 //print("cls:" + key+"\n");
84                          
85                                 var cls = new GirObject("class", key);  
86                                 cls.props = this.propsFromJSONArray("prop", value.get_object().get_array_member("props"));
87                                 cls.signals = this.propsFromJSONArray("signal", value.get_object().get_array_member("events"));
88                                 
89                                 this.classes.set(key, cls);
90                         });
91                                 
92                                 
93                         
94                                  
95                 }
96                   
97                         
98                 public string doc(string what) {
99                         return "";
100                         /*var ns = what.split(".")[0];
101
102
103                         
104                         
105                                 var gir =  Gir.factory(ns);
106                                 return   gir.doc(what);
107                                 */
108                                 
109                         //return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
110                 }
111
112                 // does not handle implements...
113                 public override GirObject? getClass(string ename)
114                 {
115                         this.load();
116                         return this.classes.get(ename);
117                         
118                 }
119                 
120                 public override Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type)
121                 {
122                         //print("Loading for " + ename);
123                         
124
125                         this.load();
126                                         // if (typeof(this.proplist[ename]) != 'undefined') {
127                                         //print("using cache");
128                                  //   return this.proplist[ename][type];
129                                 //}
130                                 // use introspection to get lists..
131                  
132                         
133                         var cls = this.classes.get(ename);
134                         var ret = new Gee.HashMap<string,GirObject>();
135                         if (cls == null) {
136                                 print("could not find class: %s\n", ename);
137                                 return ret;
138                                 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
139                 
140                         }
141
142                         //cls.parseProps();
143                         //cls.parseSignals(); // ?? needed for add handler..
144                         //cls.parseMethods(); // ?? needed for ??..
145                         //cls.parseConstructors(); // ?? needed for ??..
146
147                         //cls.overlayParent();
148
149                         switch  (type) {
150                                 
151                                 
152                                 case "props":
153                                         return cls.props;
154                                 case "signals":
155                                         return cls.signals;
156                                 case "methods":
157                                         return ret;
158                                 case "ctors":
159                                         return ret;
160                                 default:
161                                         throw new Error.INVALID_VALUE( "getPropertiesFor called with: " + type);
162                                         //var ret = new Gee.HashMap<string,GirObject>();
163                                         //return ret;
164                         
165                         }
166                 
167         
168                 //cls.overlayInterfaces(gir);
169
170
171                          
172                 }
173                 public string[] getInheritsFor(string ename)
174                 {
175                         string[] ret = {};
176                         var es = ename.split(".");
177                         var gir = Gir.factory(es[0]);
178                         
179                         var cls = gir.classes.get(es[1]);
180                         if (cls == null) {
181                                 return ret;
182                         }
183                         return cls.inheritsToStringArray();
184                         
185
186                 }
187
188
189                 public override void fillPack(JsRender.Node node,JsRender.Node parent)
190                 {   
191
192                          return;
193                 }
194                 /*
195                  *  Pulldown options for type
196                  */
197                 public override bool typeOptions(string fqn, string key, string type, out string[] opts) 
198                 {
199                         opts = {};
200                         print("get typeOptions %s (%s)%s", fqn, type, key);
201                         if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
202                                 opts = { "true", "false" };
203                                 return true;
204                          }
205                          
206                          var props = this.getPropertiesFor(fqn, "props");
207                          if (!props.has_key(key)) {
208                                  print("prop %s does not have key %s\n", fqn, key);
209                                  return false;
210                          }
211                          var pr = props.get(key);
212                          if (pr.optvalues.size < 1) {
213                                  print("prop %s no optvalues for %s\n", fqn, key);
214                                  return false;
215                          }
216                          string[] ret = {};
217                          for(var i = 0; i < pr.optvalues.size; i++) {
218                                  ret += pr.optvalues.get(i);
219                          }
220                          opts = ret;
221                          print("prop %s returning optvalues for %s\n", fqn, key);
222                          return true;
223                          
224                 }
225                 public override  List<SourceCompletionItem> suggestComplete(
226                                 JsRender.JsRender file,
227                                 JsRender.Node node,
228                                 string proptype, 
229                                 string key,
230                                 string complete_string
231                 ) { 
232                         
233                         var ret =  new List<SourceCompletionItem>();
234                         // completion rules??
235                         
236                         // Roo......
237                         
238                         // this. (based on the node type)
239                         // this.xxx // Node and any determination...
240                         
241                         if (complete_string.index_of(".",0) < 0) {
242                                 // string does not have a '.'
243                                 // offer up this / Roo / javascript keywords... / look for var string = .. in the code..
244                                 for(var i = 0; i <  JsRender.Lang.match_strings.size ; i++) {
245                                         var str = JsRender.Lang.match_strings.get(i);
246                                         if (complete_string != str && str.index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
247                                                 ret.append(new SourceCompletionItem (str, str, null, "javascript : " + str));
248                                         }
249                                         
250                                         
251                                 }
252                                 if (complete_string != "Roo" && "Roo".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
253                                         ret.append(new SourceCompletionItem ("Roo", "Roo", null, "Roo library"));
254                                 }
255
256                                 return ret;
257                         }
258                         // got at least one ".".
259                         var parts = complete_string.split(".");
260                         var curtype = "";
261                         var cur_instance = false;
262                         if (parts[0] == "this") {
263                                 // work out from the node, what the type is...
264                                 if (node == null) {
265                                         return ret; // no idea..
266                                 }
267                                 curtype = node.fqn();
268                                 cur_instance = true;
269                         }
270                         if (parts[0] == "Roo") {        
271                                 curtype = "Roo";
272                                 cur_instance = false;
273                         }
274                         
275                         var prevbits = parts[0] + ".";
276                         for(var i =0; i < parts.length; i++) {
277                                 var is_last = i == parts.length -1;
278                                 
279                                 // look up all the properties of the type...
280                                 var cls = this.getClass(curtype);
281                                 if (cls == null) {
282                                         return ret;
283                                 }
284                                 
285                                 if (!is_last) {
286                                 
287                                         // only exact matches from here on...
288                                         if (cur_instance) {
289                                                 if (cls.props.has_key(parts[i])) {
290                                                         var prop = cls.props.get(parts[i]);
291                                                         if (prop.type.index_of(".",0) > -1) {
292                                                                 // type is another roo object..
293                                                                 curtype = prop.type;
294                                                                 prevbits += parts[i] + ".";
295                                                                 continue;
296                                                         }
297                                                         return ret;
298                                                 }
299                                                 // check methods?? - we do not export that at present..
300                                                 return ret;      //no idea...
301                                         }
302                                 
303                                         // not a instance..
304                                         //look for child classes.
305                                         var citer = this.classes.map_iterator();
306                                         var foundit = false;
307                                         while (citer.next()) {
308                                                 var scls = citer.get_key();
309                                                 var look = prevbits + parts[i];
310                                                 if (scls.index_of(look,0) != 0) {
311                                                         continue;
312                                                 }
313                                                 // got a starting match..
314                                                 curtype = look;
315                                                 cur_instance = false;
316                                                 foundit =true;
317                                                 break;
318                                         }
319                                         if (!foundit) {
320                                                 return ret;
321                                         }
322                                         prevbits += parts[i] + ".";
323                                         continue;
324                                 }
325                                 // got to the last element..
326                                 print("Got last element\n");
327                                 if (curtype == "") { // should not happen.. we would have returned already..
328                                         return ret;
329                                 }
330                                 print("Got last element type %s\n",curtype);
331                                 if (!cur_instance) {
332                                         print("matching instance");
333                                         // it's a static reference..
334                                         var citer = this.classes.map_iterator();
335                                         while (citer.next()) {
336                                                 var scls = citer.get_key();
337                                                 var look = prevbits + parts[i];
338                                                 if (scls.index_of(look,0) != 0) {
339                                                         continue;
340                                                 }
341                                                 // got a starting match..
342                                                 ret.append(new SourceCompletionItem (
343                                                         scls,
344                                                         scls, 
345                                                         null, 
346                                                         scls));
347                                         }
348                                         return ret;
349                                 }
350                                 
351                                 
352                                 // get the properties / methods and subclasses.. of cls..
353                                 // we have cls.. - see if the string matches any of the properties..
354                                 var citer = cls.props.map_iterator();
355                                 while (citer.next()) {
356                                         var prop = citer.get_value();
357                                         // does the name start with ...
358                                         if (prop.name.index_of(parts[i],0) != 0) {
359                                                 continue;
360                                         }
361                                         // got a matching property...
362                                         
363                                         ret.append(new SourceCompletionItem (
364                                                         cls.name + "." + prop.name, 
365                                                         prevbits + prop.name, 
366                                                         null, 
367                                                         prop.doctxt));
368                                 }
369                                          
370                                         
371                                 return ret;     
372                                         
373                                         
374                                 
375                                         
376                                 
377                         }
378                         
379                          
380                         
381                         
382                         
383                         
384                         return ret;
385                 }
386     }
387 }
388