9 public class Introspect.El : Object
23 public class Gtk : Palete {
25 public Gee.ArrayList<string> package_cache;
34 var context = new Vala.CodeContext ();
36 this.package_cache = this.loadPackages(Path.get_dirname (context.get_vapi_path("glib-2.0")));
38 // various loader methods..
42 //this.comments = { };
46 public override void load () {
48 this.loadUsageFile(BuilderApplication.configDirectory() + "/resources/GtkUsage.txt");
53 public string doc(string what) {
54 var ns = what.split(".")[0];
55 var gir = Gir.factory(ns);
58 //return typeof(this.comments[ns][what]) == 'undefined' ? '' : this.comments[ns][what];
61 // does not handle implements...
62 public override GirObject? getClass(string ename)
65 var es = ename.split(".");
66 var gir = Gir.factory(es[0]);
68 return gir.classes.get(es[1]);
72 public override Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type)
74 //print("Loading for " + ename);
78 // if (typeof(this.proplist[ename]) != 'undefined') {
79 //print("using cache");
80 // return this.proplist[ename][type];
82 // use introspection to get lists..
84 var es = ename.split(".");
85 var gir = Gir.factory(es[0]);
87 var cls = gir.classes.get(es[1]);
89 var ret = new Gee.HashMap<string,GirObject>();
91 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
96 //cls.parseSignals(); // ?? needed for add handler..
97 //cls.parseMethods(); // ?? needed for ??..
98 //cls.parseConstructors(); // ?? needed for ??..
112 throw new Error.INVALID_VALUE( "getPropertiesFor called with: " + type);
113 //var ret = new Gee.HashMap<string,GirObject>();
119 //cls.overlayInterfaces(gir);
124 public string[] getInheritsFor(string ename)
128 var cls = Gir.factoryFqn(ename);
130 if (cls == null || cls.nodetype != "Class") {
131 print("getInheritsFor:could not find cls: %s\n", ename);
135 return cls.inheritsToStringArray();
140 public override void fillPack(JsRender.Node node,JsRender.Node parent)
143 string inherits = string.joinv(" ",
144 this.getInheritsFor (node.fqn())) + " ";
145 inherits += node.fqn() + " ";
146 //print ("fillPack:Inherits : %s\n", inherits);
147 // parent.fqn() method ( node.fqn()
148 var methods = this.getPropertiesFor (parent.fqn(), "methods");
150 var res = new Gee.HashMap<string,string>();
151 var map = methods.map_iterator();
154 var n = map.get_key();
155 //print ("fillPack:checking method %s\n", n);
157 var meth = map.get_value();
158 if (meth.paramset == null || meth.paramset.params.size < 1) {
159 print ("fillPack:c -- no params\n");
163 var fp = meth.paramset.params.get(0);
165 var type = Gir.fqtypeLookup(fp.type, meth.ns);
166 print ("fillPack:first param type is %s\n", type);
169 if (!inherits.contains(" " + type + " ")) {
174 var pack = meth.name;
175 for(var i =1; i < meth.paramset.params.size; i++) {
176 var ty = Gir.fqtypeLookup(meth.paramset.params.get(i).type, meth.ns);
177 pack += "," + Gir.guessDefaultValueForType(ty);
180 print ("fillPack:add pack: -- %s\n",pack );
182 res.set(meth.name, pack);
190 if (res.has_key("pack_start")) {
191 node.props.set("* pack", res.get("pack_start"));
194 if (res.has_key("add")) {
195 node.props.set("* pack", res.get("add"));
198 var riter = res.map_iterator();
199 while(riter.next()) {
200 node.props.set("* pack", riter.get_value());
206 public Gee.ArrayList<string> packages(Project.Gtk gproject)
208 var vapidirs = gproject.vapidirs();
209 var ret = new Gee.ArrayList<string>();
210 ret.add_all(this.package_cache);
211 for(var i = 0; i < vapidirs.length;i++) {
212 var add = this.loadPackages(vapidirs[i]);
213 for (var j=0; j < add.size; j++) {
214 if (ret.contains(add.get(j))) {
225 public Gee.ArrayList<string> loadPackages(string dirname)
228 var ret = new Gee.ArrayList<string>();
229 //this.package_cache = new Gee.ArrayList<string>();
232 var dir = File.new_for_path(dirname);
234 var file_enum = dir.enumerate_children(
235 GLib.FileAttribute.STANDARD_DISPLAY_NAME,
236 GLib.FileQueryInfoFlags.NONE,
242 while ((next_file = file_enum.next_file(null)) != null) {
243 var fn = next_file.get_display_name();
244 if (!Regex.match_simple("\\.vapi$", fn)) {
247 ret.add(Path.get_basename(fn).replace(".vapi", ""));
250 print("oops - something went wrong scanning the packages\n");
256 public override bool typeOptions(string fqn, string key, string type, out string[] opts)
259 print("get typeOptions %s (%s)%s", fqn, type, key);
260 if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
261 opts = { "true", "false" };
264 var gir= Gir.factoryFqn(type) ;
266 print("could not find Gir data for %s\n", key);
269 print ("Got type %s", gir.asJSONString());
270 if (gir.nodetype != "Enum") {
274 var iter = gir.consts.map_iterator();
277 ret += (type + "." + iter.get_value().name);
280 if (ret.length > 0) {
290 public override List<SourceCompletionItem> suggestComplete(
291 JsRender.JsRender file,
295 string complete_string
298 var ret = new List<SourceCompletionItem>();
299 // completion rules??
303 // this. (based on the node type)
304 // this.xxx // Node and any determination...
306 if (complete_string.index_of(".",0) < 0) {
307 // string does not have a '.'
308 // offer up this / Roo / javascript keywords... / look for var string = .. in the code..
309 for(var i = 0; i < JsRender.Lang.match_strings.size ; i++) {
310 var str = JsRender.Lang.match_strings.get(i);
311 if (complete_string != str && str.index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
312 ret.append(new SourceCompletionItem (str, str, null, "javascript : " + str));
317 if (complete_string != "Roo" && "Roo".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
318 ret.append(new SourceCompletionItem ("Roo - A Roo class", "Roo", null, "Roo library"));
320 if (complete_string != "_this" && "_this".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
321 ret.append(new SourceCompletionItem ("_this - the top level element", "_this", null, "Top level element"));
325 // got at least one ".".
326 var parts = complete_string.split(".");
328 var cur_instance = false;
329 if (parts[0] == "this") {
330 // work out from the node, what the type is...
332 print("node is empty - no return\n");
333 return ret; // no idea..
335 curtype = node.fqn();
338 if (parts[0] == "Roo") {
340 cur_instance = false;
343 var prevbits = parts[0] + ".";
344 for(var i =1; i < parts.length; i++) {
345 print("matching %d/%d\n", i, parts.length);
346 var is_last = i == parts.length -1;
348 // look up all the properties of the type...
349 var cls = this.getClass(curtype);
351 print("could not get class of curtype %s\n", curtype);
357 // only exact matches from here on...
359 if (cls.props.has_key(parts[i])) {
360 var prop = cls.props.get(parts[i]);
361 if (prop.type.index_of(".",0) > -1) {
362 // type is another roo object..
364 prevbits += parts[i] + ".";
372 // check methods?? - we do not export that at present..
373 return ret; //no idea...
377 //look for child classes.
378 var citer = this.classes.map_iterator();
380 while (citer.next()) {
381 var scls = citer.get_key();
382 var look = prevbits + parts[i];
383 if (scls.index_of(look,0) != 0) {
386 // got a starting match..
388 cur_instance = false;
395 prevbits += parts[i] + ".";
398 // got to the last element..
399 print("Got last element\n");
400 if (curtype == "") { // should not happen.. we would have returned already..
403 print("Got last element type %s\n",curtype);
405 print("matching instance");
406 // it's a static reference..
407 var citer = this.classes.map_iterator();
408 while (citer.next()) {
409 var scls = citer.get_key();
410 var look = prevbits + parts[i];
411 if (parts[i].length > 0 && scls.index_of(look,0) != 0) {
414 // got a starting match..
415 ret.append(new SourceCompletionItem (
423 print("matching property");
427 var citer = cls.methods.map_iterator();
428 while (citer.next()) {
429 var prop = citer.get_value();
430 // does the name start with ...
431 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
434 // got a matching property...
436 ret.append(new SourceCompletionItem (
437 prop.name + prop.sig + " : ("+ prop.propertyof + ")",
438 prevbits + prop.name + "(",
443 // get the properties / methods and subclasses.. of cls..
444 // we have cls.. - see if the string matches any of the properties..
445 citer = cls.props.map_iterator();
446 while (citer.next()) {
447 var prop = citer.get_value();
448 // does the name start with ...
449 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
452 // got a matching property...
454 ret.append(new SourceCompletionItem (
455 prop.name + " : " + prop.type + " ("+ prop.propertyof + ")",
456 prevbits + prop.name,