9 public class Introspect.El : Object
23 public class Roo : Palete {
25 Gee.ArrayList<string> top_classes;
26 public static Gee.HashMap<string,GirObject>? classes_cache = null;
27 public static Gee.ArrayList<string>? top_classes_cache = null;
29 public Roo(Project.Project project)
36 this.top_classes = new Gee.ArrayList<string>();
39 this.load(); // ? initialize the roodata?
43 Gee.HashMap<string,GirObject> propsFromJSONArray(string type, Json.Array ar, GirObject cls)
46 var ret = new Gee.HashMap<string,GirObject>();
48 for (var i =0 ; i < ar.get_length(); i++) {
49 var o = ar.get_object_element(i);
50 var name = o.get_string_member("name");
51 var prop = new GirObject(type, name );
53 prop.type = o.get_string_member("type");
54 prop.doctxt = o.get_string_member("desc");
55 prop.propertyof = o.has_member("memberOf") ? o.get_string_member("memberOf") : "";
56 if (prop.propertyof.length < 1) {
57 prop.propertyof = cls.name;
60 // this is the function default.
61 prop.sig = o.has_member("sig") ? o.get_string_member("sig") : "";
63 if (o.has_member("optvals") ) {
64 var oar = o.get_array_member("optvals");
66 for (var oi = 0; oi < oar.get_length(); oi++) {
67 prop.optvalues.add(oar.get_string_element(oi));
72 //print(type + ":" + name +"\n");
79 public override void load () {
81 if (this.classes != null) {
84 if (Roo.classes_cache != null) {
85 this.classes = Roo.classes_cache;
86 this.top_classes = Roo.top_classes_cache ;
91 // this.loadUsageFile(BuilderApplication.configDirectory() + "/resources/RooUsage.txt");
92 this.classes = new Gee.HashMap<string,GirObject>();
93 var add_to = new Gee.HashMap<string,Gee.ArrayList<string>>();
95 var pa = new Json.Parser();
97 pa.load_from_file(BuilderApplication.configDirectory() + "/resources/roodata.json");
98 } catch(GLib.Error e) {
99 GLib.error("Could not load %s",BuilderApplication.configDirectory() + "/resources/roodata.json");
101 var node = pa.get_root();
103 var clist = node.get_object(); /// was in data... .get_object_member("data");
104 clist.foreach_member((o , key, value) => {
105 //print("cls:" + key+"\n");
107 var cls = new GirObject("class", key);
108 cls.props = this.propsFromJSONArray("prop", value.get_object().get_array_member("props"),cls);
109 cls.signals = this.propsFromJSONArray("signal", value.get_object().get_array_member("events"),cls);
112 if (value.get_object().has_member("methods")) {
113 cls.methods = this.propsFromJSONArray("method", value.get_object().get_array_member("methods"),cls);
115 if (value.get_object().has_member("implementations")) {
116 var vcn = value.get_object().get_array_member("implementations");
117 for (var i =0 ; i < vcn.get_length(); i++) {
118 cls.implementations.add(vcn.get_string_element(i));
124 if (value.get_object().has_member("tree_children")) {
125 var vcn = value.get_object().get_array_member("tree_children");
126 for (var i =0 ; i < vcn.get_length(); i++) {
127 var ad_c = vcn.get_string_element(i);
128 if (!cls.valid_cn.contains(ad_c)) {
129 cls.valid_cn.add( ad_c );
131 if (!add_to.has_key(ad_c)) {
132 add_to.set(ad_c, new Gee.ArrayList<string>());
134 if (!add_to.get(ad_c).contains(cls.name)) {
135 add_to.get(ad_c).add(cls.name);
145 if (value.get_object().has_member("tree_parent")) {
146 var vcn = value.get_object().get_array_member("tree_parent");
147 for (var i =0 ; i < vcn.get_length(); i++) {
148 if ("builder" == vcn.get_string_element(i)) {
149 // this class can be added to the top level.
150 GLib.debug("Add %s to *top", cls.name);
152 this.top_classes.add(cls.name);
159 this.classes.set(key, cls);
162 // look for properties of classes, that are atually clasess
163 // eg. Roo.data.Store has proxy and reader..
166 foreach(var cls in this.classes.values) {
167 foreach(var gir_obj in cls.props.values) {
168 var types = gir_obj.type.split("|");
169 for(var i =0; i < types.length; i++) {
172 if (/^Roo\./.match(type) && classes.has_key(type)) {
175 cls.valid_cn.add(type + ":" + gir_obj.name );
176 // Roo.bootstrap.panel.Content:east
177 // also means that Roo.bootstrap.panel.Grid:east works
178 var prop_type = classes.get(type);
179 foreach(var imp_str in prop_type.implementations) {
180 //GLib.debug("addChild for %s - child= %s:%s", cls.name, imp_str, gir_obj.name);
181 cls.valid_cn.add(imp_str + ":" + gir_obj.name);
182 if (!add_to.has_key(imp_str)) {
183 add_to.set( imp_str, new Gee.ArrayList<string>());
185 if (!add_to.get( imp_str).contains(cls.name)) {
186 add_to.get( imp_str ).add(cls.name );
192 if (!add_to.has_key( type)) {
193 add_to.set( type, new Gee.ArrayList<string>());
195 if (!add_to.get(type).contains(cls.name)) {
196 add_to.get( type ).add(cls.name );
203 foreach(var cls in this.classes.values) {
204 if (add_to.has_key(cls.name)) {
205 cls.can_drop_onto = add_to.get(cls.name);
208 Roo.classes_cache = this.classes;
209 Roo.top_classes_cache = this.top_classes;
213 public string doc(string what) {
215 /*var ns = what.split(".")[0];
220 var gir = Gir.factory(ns);
221 return gir.doc(what);
224 //return typeof(this.comments[ns][what]) == 'undefined' ? '' : this.comments[ns][what];
227 // does not handle implements...
228 public override GirObject? getClass(string ename)
231 return this.classes.get(ename);
237 public override Gee.HashMap<string,GirObject> getPropertiesFor(string ename, JsRender.NodePropType ptype)
239 //print("Loading for " + ename);
243 // if (typeof(this.proplist[ename]) != 'undefined') {
244 //print("using cache");
245 // return this.proplist[ename][type];
247 // use introspection to get lists..
250 var cls = this.classes.get(ename);
251 var ret = new Gee.HashMap<string,GirObject>();
253 print("could not find class: %s\n", ename);
255 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
260 //cls.parseSignals(); // ?? needed for add handler..
261 //cls.parseMethods(); // ?? needed for ??..
262 //cls.parseConstructors(); // ?? needed for ??..
264 //cls.overlayParent();
269 case JsRender.NodePropType.PROP:
270 return this.filterProps(cls.props);
271 case JsRender.NodePropType.LISTENER:
273 case JsRender.NodePropType.METHOD:
275 case JsRender.NodePropType.CTOR:
278 GLib.error( "getPropertiesFor called with: " + ptype.to_string());
279 //var ret = new Gee.HashMap<string,GirObject>();
285 //cls.overlayInterfaces(gir);
291 // removes all the properties where the type contains '.' ?? << disabled now..
293 public Gee.HashMap<string,GirObject> filterProps(Gee.HashMap<string,GirObject> props)
295 // we shold probably cache this??
297 var outprops = new Gee.HashMap<string,GirObject>();
299 foreach(var k in props.keys) {
300 var val = props.get(k);
311 //if (!val.type.contains(".")) {
318 // do nothing? - classes not allowed?
329 public string[] getInheritsFor(string ename)
332 var es = ename.split(".");
333 var gir = Gir.factory(null, es[0]);
335 var cls = gir.classes.get(es[1]);
339 return cls.inheritsToStringArray();
346 * Pulldown options for type
348 public override bool typeOptions(string fqn, string key, string type, out string[] opts)
351 print("get typeOptions %s (%s)%s", fqn, type, key);
352 if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
353 opts = { "true", "false" };
357 var props = this.getPropertiesFor(fqn, JsRender.NodePropType.PROP);
358 if (!props.has_key(key)) {
359 print("prop %s does not have key %s\n", fqn, key);
362 var pr = props.get(key);
363 if (pr.optvalues.size < 1) {
364 print("prop %s no optvalues for %s\n", fqn, key);
368 for(var i = 0; i < pr.optvalues.size; i++) {
369 ret += pr.optvalues.get(i);
372 print("prop %s returning optvalues for %s\n", fqn, key);
376 public override Gee.ArrayList<CompletionProposal> suggestComplete(
377 JsRender.JsRender file,
379 JsRender.NodeProp? xxprop,
380 string complete_string
383 var ret = new Gee.ArrayList<CompletionProposal>();
386 // completion rules??
390 // this. (based on the node type)
391 // this.xxx // Node and any determination...
393 if (complete_string.index_of(".",0) < 0) {
394 // string does not have a '.'
395 // offer up this / Roo / javascript keywords... / look for var string = .. in the code..
396 for(var i = 0; i < JsRender.Lang.match_strings.size ; i++) {
397 var str = JsRender.Lang.match_strings.get(i);
398 if (complete_string != str && str.index_of(complete_string,0) == 0 ) {
399 // should we ignore exact matches... ???tr,str,
400 var sci = new CompletionProposal(str,str, "javascript: " + str);
407 if (complete_string != "Roo" && "Roo".index_of(complete_string,0) == 0 ) {
408 // should we ignore exact matches... ???
410 var sci = new CompletionProposal("Roo - A Roo class","Roo", "Roo Library");
414 if (complete_string != "_this" && "_this".index_of(complete_string,0) == 0 ) {
415 // should we ignore exact matches... ???
416 var sci = new CompletionProposal("_this - Reference to the global pointer to the files main class instance",
417 "_this", "Reference to the global pointer to the files main class instance");
423 // got at least one ".".
424 var parts = complete_string.split(".");
426 var cur_instance = false;
427 if (parts[0] == "this") {
428 // work out from the node, what the type is...
430 print("node is empty - no return\n");
431 return ret; // no idea..
433 curtype = node.fqn();
436 if (parts[0] == "Roo") {
438 cur_instance = false;
441 var prevbits = parts[0] + ".";
442 for(var i =1; i < parts.length; i++) {
443 print("matching %d/%d\n", i, parts.length);
444 var is_last = i == parts.length -1;
446 // look up all the properties of the type...
447 var cls = this.getClass(curtype);
449 print("could not get class of curtype %s\n", curtype);
455 // only exact matches from here on...
457 if (cls.props.has_key(parts[i])) {
458 var prop = cls.props.get(parts[i]);
459 if (prop.type.index_of(".",0) > -1) {
460 // type is another roo object..
462 prevbits += parts[i] + ".";
470 // check methods?? - we do not export that at present..
471 return ret; //no idea...
475 //look for child classes.
476 var citer = this.classes.map_iterator();
478 while (citer.next()) {
479 var scls = citer.get_key();
480 var look = prevbits + parts[i];
481 if (scls.index_of(look,0) != 0) {
484 // got a starting match..
486 cur_instance = false;
493 prevbits += parts[i] + ".";
496 // got to the last element..
497 print("Got last element\n");
498 if (curtype == "") { // should not happen.. we would have returned already..
501 print("Got last element type %s\n",curtype);
503 print("matching instance");
504 // it's a static reference..
505 var citer = this.classes.map_iterator();
506 while (citer.next()) {
507 var scls = citer.get_key();
508 var look = prevbits + parts[i];
509 if (parts[i].length > 0 && scls.index_of(look,0) != 0) {
513 // got a starting match..
514 var sci = new CompletionProposal(scls,scls,scls);
519 print("matching property");
523 var citer = cls.methods.map_iterator();
524 while (citer.next()) {
525 var prop = citer.get_value();
526 // does the name start with ...
527 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
530 // got a matching property...
534 var sci = new CompletionProposal(prop.name + prop.sig + " : ("+ prop.propertyof + ")",
535 prevbits + prop.name + "(",prop.doctxt);
540 // get the properties / methods and subclasses.. of cls..
541 // we have cls.. - see if the string matches any of the properties..
542 citer = cls.props.map_iterator();
543 while (citer.next()) {
544 var prop = citer.get_value();
545 // does the name start with ...
546 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
549 // got a matching property..
550 var sci = new CompletionProposal(prop.name + prop.type + " : ("+ prop.propertyof + ")",
551 prevbits + prop.name + "(",prop.doctxt);
575 public override Gee.ArrayList<string> getChildList(string in_rval, bool with_prop)
577 if (this.top_classes.size < 1) {
583 var ar = this.top_classes;
584 if (in_rval != "*top") {
585 if (this.classes.has_key(in_rval)) {
586 // some of these children will be eg: Roo.bootstrap.layout.Region:center
587 ar = this.classes.get(in_rval).valid_cn;
589 ar = new Gee.ArrayList<string>();
594 var ret = new Gee.ArrayList<string>();
595 foreach(var v in ar) {
596 if (v.contains(":")) {
604 GLib.debug("getChildList for %s returns %d items", in_rval, ar.size);
607 //return this.original_getChildList( in_rval);
612 public override Gee.ArrayList<string> getDropList(string rval)
615 if (this.dropCache.has_key(rval)) {
616 return this.dropCache.get(rval);
618 // we might be dragging Roo.bootstrap.layout.Region:center
619 // in which case we need to lookup Roo.bootstrap.layout.Region
620 // and see if it's has can_drop_onto
621 var ret = new Gee.ArrayList<string>();
622 var cls = this.classes.get(rval);
624 if (cls == null && rval.contains(":")) {
625 var rr = rval.substring(0,rval.index_of(":"));
626 GLib.debug("Converted classname to %s", rr);
627 cls = this.classes.get(rr);
630 return ret; //nothing..
633 foreach(var str in cls.can_drop_onto) {
637 //GLib.debug("getDropList for %s return[] %s", rval, string.joinv(", ", ret));
638 this.dropCache.set(rval,ret);
643 //return this.default_getDropList(rval);
645 public override JsRender.Node fqnToNode(string fqn)
647 var ret = new JsRender.Node();
649 // any default requred proerties?