9 public class Introspect.El : Object
23 public class Gtk : Palete {
25 public Gee.ArrayList<string> package_cache;
27 public Gtk(Project.Project project)
32 var context = new Vala.CodeContext ();
34 this.package_cache = this.loadPackages(Path.get_dirname (context.get_vapi_path("glib-2.0")));
35 this.package_cache.add_all(
36 this.loadPackages(Path.get_dirname (context.get_vapi_path("gee-0.8")))
39 // various loader methods..
43 //this.comments = { };
47 public override void load () {
49 this.loadUsageFile(BuilderApplication.configDirectory() + "/resources/GtkUsage.txt");
54 public string doc(string what) {
55 var ns = what.split(".")[0];
56 var gir = Gir.factory(this.project,ns);
59 //return typeof(this.comments[ns][what]) == 'undefined' ? '' : this.comments[ns][what];
62 // does not handle implements...
63 public override GirObject? getClass(string ename)
66 var es = ename.split(".");
67 var gir = Gir.factory(this.project,es[0]);
69 return gir.classes.get(es[1]);
73 public override Gee.HashMap<string,GirObject> getPropertiesFor( string ename, string type)
75 //print("Loading for " + ename);
79 // if (typeof(this.proplist[ename]) != 'undefined') {
80 //print("using cache");
81 // return this.proplist[ename][type];
83 // use introspection to get lists..
85 var es = ename.split(".");
86 var gir = Gir.factory(this.project,es[0]);
88 print("WARNING = could not load vapi for %s (%s)\n", ename , es[0]);
89 return new Gee.HashMap<string,GirObject>();
91 var cls = gir.classes.get(es[1]);
93 var ret = new Gee.HashMap<string,GirObject>();
95 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
100 //cls.parseSignals(); // ?? needed for add handler..
101 //cls.parseMethods(); // ?? needed for ??..
102 //cls.parseConstructors(); // ?? needed for ??..
104 cls.overlayParent(this.project);
116 throw new Error.INVALID_VALUE( "getPropertiesFor called with: " + type);
117 //var ret = new Gee.HashMap<string,GirObject>();
123 //cls.overlayInterfaces(gir);
128 public string[] getInheritsFor(string ename)
132 var cls = Gir.factoryFqn(this.project,ename);
134 if (cls == null || cls.nodetype != "Class") {
135 print("getInheritsFor:could not find cls: %s\n", ename);
139 return cls.inheritsToStringArray();
144 public override void fillPack(JsRender.Node node,JsRender.Node parent)
147 string inherits = string.joinv(" ",
148 this.getInheritsFor (node.fqn())) + " ";
149 inherits += node.fqn() + " ";
150 //print ("fillPack:Inherits : %s\n", inherits);
151 // parent.fqn() method ( node.fqn()
152 var methods = this.getPropertiesFor (parent.fqn(), "methods");
154 var res = new Gee.HashMap<string,string>();
155 var map = methods.map_iterator();
158 var n = map.get_key();
159 //print ("fillPack:checking method %s\n", n);
161 var meth = map.get_value();
162 if (meth.paramset == null || meth.paramset.params.size < 1) {
163 print ("fillPack:c -- no params\n");
167 var fp = meth.paramset.params.get(0);
169 var type = Gir.fqtypeLookup(this.project, fp.type, meth.ns);
170 print ("fillPack:first param type is %s\n", type);
173 if (!inherits.contains(" " + type + " ")) {
178 var pack = meth.name;
179 for(var i =1; i < meth.paramset.params.size; i++) {
180 var ty = Gir.fqtypeLookup(this.project,meth.paramset.params.get(i).type, meth.ns);
181 pack += "," + Gir.guessDefaultValueForType(ty);
184 print ("fillPack:add pack: -- %s\n",pack );
186 res.set(meth.name, pack);
194 if (res.has_key("pack_start")) {
195 node.props.set("* pack", res.get("pack_start"));
198 if (res.has_key("add")) {
199 node.props.set("* pack", res.get("add"));
202 var riter = res.map_iterator();
203 while(riter.next()) {
204 node.props.set("* pack", riter.get_value());
210 public Gee.ArrayList<string> packages(Project.Gtk gproject)
212 var vapidirs = gproject.vapidirs();
213 var ret = new Gee.ArrayList<string>();
214 ret.add_all(this.package_cache);
215 for(var i = 0; i < vapidirs.length;i++) {
216 var add = this.loadPackages(vapidirs[i]);
217 for (var j=0; j < add.size; j++) {
218 if (ret.contains(add.get(j))) {
229 public Gee.ArrayList<string> loadPackages(string dirname)
232 var ret = new Gee.ArrayList<string>();
233 //this.package_cache = new Gee.ArrayList<string>();
235 if (!GLib.FileUtils.test(dirname, FileTest.IS_DIR)) {
236 print("opps package directory %s does not exist", dirname);
240 var dir = File.new_for_path(dirname);
244 var file_enum = dir.enumerate_children(
245 GLib.FileAttribute.STANDARD_DISPLAY_NAME,
246 GLib.FileQueryInfoFlags.NONE,
252 while ((next_file = file_enum.next_file(null)) != null) {
253 var fn = next_file.get_display_name();
254 if (!Regex.match_simple("\\.vapi$", fn)) {
257 ret.add(Path.get_basename(fn).replace(".vapi", ""));
260 print("oops - something went wrong scanning the packages\n");
266 public override bool typeOptions(string fqn, string key, string type, out string[] opts)
269 print("get typeOptions %s (%s)%s", fqn, type, key);
270 if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
271 opts = { "true", "false" };
274 var gir= Gir.factoryFqn(this.project,type) ;
276 print("could not find Gir data for %s\n", key);
279 print ("Got type %s", gir.asJSONString());
280 if (gir.nodetype != "Enum") {
284 var iter = gir.consts.map_iterator();
287 ret += (type + "." + iter.get_value().name);
290 if (ret.length > 0) {
300 public override List<SourceCompletionItem> suggestComplete(
301 JsRender.JsRender file,
305 string complete_string
308 var ret = new List<SourceCompletionItem>();
309 // completion rules??
311 // make sure data is loaded
312 Gir.factory(this.project,"Gtk");
316 // this. (based on the node type)
317 // this.xxx // Node and any determination...
319 if (complete_string.index_of(".",0) < 0) {
320 // string does not have a '.'
321 // offer up vala keywords... / _this .. / look for var string = .. in the code..
323 var max = (int)Vala.TokenType.YIELD +1;
324 for (var i =0; i < max;i++) {
325 var m = (Vala.TokenType)i;
326 var s = m.to_string();
327 var ss = s.slice(1,-1);
328 if (s[0] == '`' && GLib.Regex.match_simple("^[a-z]+$", ss) &&
329 complete_string != ss && ss.index_of(complete_string,0) == 0 ) {
330 ret.append(new SourceCompletionItem (ss, ss, null, "vala : " + ss));
333 var miter = ((Project.Gtk)this.project).gir_cache.map_iterator();
334 while (miter.next()) {
335 var ss = miter.get_key();
337 if (complete_string != ss && ss.index_of(complete_string,0) == 0 ) {
338 ret.append(new SourceCompletionItem (ss, ss, null, "vala namespace : " + ss));
343 if (complete_string != "_this" && "_this".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
344 ret.append(new SourceCompletionItem ("_this - the top level element", "_this", null, "Top level element"));
352 // got at least one ".".
353 var parts = complete_string.split(".");
355 var cur_instance = false;
356 if (parts[0] == "this") {
357 // work out from the node, what the type is...
359 print("node is empty - no return\n");
360 return ret; // no idea..
362 curtype = "*" + node.fqn();
365 if (((Project.Gtk)this.project).gir_cache.get(parts[0]) == null) {
370 // all Gtk.... etc.. types...
373 //if (parts[0] == "Roo") {
375 // cur_instance = false;
378 var prevbits = parts[0] + ".";
379 for(var i =1; i < parts.length; i++) {
380 print("matching %d/%d\n", i, parts.length);
381 var is_last = i == parts.length -1;
385 // look up all the properties of the type...
386 var cls = Gir.factoryFqn(this.project,curtype);
387 if (cls == null && curtype[0] != '*') {
388 print("could not get class of curtype %s\n", curtype);
394 if (curtype[0] == '*' && parts[i] == "el") {
395 curtype = curtype.substring(1);
396 prevbits += parts[i] + ".";
400 // only exact matches from here on...
405 if (cls.props.has_key(parts[i])) {
406 var prop = cls.props.get(parts[i]);
407 if (prop.type.index_of(".",0) > -1) {
408 // type is another roo object..
410 prevbits += parts[i] + ".";
418 // check methods?? - we do not export that at present..
419 return ret; //no idea...
421 var look = prevbits + parts[i];
422 var scls = Gir.factoryFqn(this.project,look);
427 prevbits += parts[i] + ".";
432 // got to the last element..
433 print("Got last element\n");
434 if (curtype == "") { // should not happen.. we would have returned already..
437 print("Got last element type %s\n",curtype);
439 print("matching instance");
440 // it's a static reference..
441 var citer = cls.classes.map_iterator();
442 while (citer.next()) {
443 var scls = citer.get_key();
445 if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
448 // got a starting match..
449 ret.append(new SourceCompletionItem (
456 citer = cls.methods.map_iterator();
457 while (citer.next()) {
458 var scls = citer.get_key();
460 if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
463 // got a starting match..
464 ret.append(new SourceCompletionItem (
465 prevbits + scls + citer.get_value().sig ,
472 citer = cls.consts.map_iterator();
473 while (citer.next()) {
474 var scls = citer.get_key();
476 if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
479 // got a starting match..
480 ret.append(new SourceCompletionItem (
481 prevbits + scls + citer.get_value().sig ,
490 print("matching property");
496 var citer = cls.methods.map_iterator();
497 while (citer.next()) {
498 var prop = citer.get_value();
499 // does the name start with ...
500 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
503 // got a matching property...
505 ret.append(new SourceCompletionItem (
506 prop.name + prop.sig + " : ("+ prop.propertyof + ")",
507 prevbits + prop.name + "(",
512 // get the properties / methods and subclasses.. of cls..
513 // we have cls.. - see if the string matches any of the properties..
514 citer = cls.props.map_iterator();
515 while (citer.next()) {
516 var prop = citer.get_value();
517 // does the name start with ...
518 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
521 // got a matching property...
523 ret.append(new SourceCompletionItem (
524 prop.name + " : " + prop.type + " ("+ prop.propertyof + ")",
525 prevbits + prop.name,
547 public override string[] getChildList(string in_rval)
549 return this.original_getChildList( in_rval);
551 public override string[] getDropList(string rval)
553 return this.default_getDropList(rval);