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