using Gtk; namespace Palete { public class UsageMap : Object { Gee.HashMap> implementors; Gee.HashMap childType; Gee.HashMap no_children; Gee.HashMap is_abstract; Gee.HashMap> extends; public UsageMap() { this.implementors = new Gee.HashMap>(); this.extends = new Gee.HashMap>(); this.childType = new Gee.HashMap(); this.no_children = new Gee.HashMap(); this.is_abstract = new Gee.HashMap(); var pa = new Json.Parser(); pa.load_from_file(BuilderApplication.configDirectory() + "/resources/flutter_tree.json"); var node = pa.get_root(); this.addArray(node.get_array()); this.removeNonChild(); } private void addArray(Json.Array ar) { for(var i=0;i< ar.get_length(); i++) { this.addObject(ar.get_object_element(i)); } } private void addObject(Json.Object o) { this.addArray(o.get_array_member("cn")); var name = o.get_string_member("name"); if (!o.get_boolean_member("is_class")) { return; } if (o.get_array_member("implementors").get_length() > 0) { this.implementors.set(name , this.jsonStringArray(o.get_array_member("implementors"))); } if (o.get_array_member("extends").get_length() > 0) { this.extends.set(name , this.jsonStringArray(o.get_array_member("extends"))); } if (o.get_string_member("childtype").length > 0) { this.childType.set( name, o.get_string_member("childtype")); this.no_children.set( name, (int) o.get_int_member("childtypes")); } } private Gee.ArrayList jsonStringArray(Json.Array ar) { var ret = new Gee.ArrayList(); for(var i=0;i< ar.get_length(); i++) { ret.add(ar.get_string_element(i)); } return ret; } public void removeNonChild() { // do we need to clean this up? // remove all the unrelated objects? } public Gee.ArrayList possibleChildrenOf(string n) { GLib.debug("possibleChildrenOf %s", n); var ret = new Gee.ArrayList(); if (!this.childType.has_key(n)) { return ret; } var ch = this.childType.get(n); GLib.debug("childType %s", ch); if (this.is_abstract.has_key(ch) && !this.is_abstract.get(ch)) { GLib.debug("add Implementor (self) %s", ch); ret.add(ch); // it's not abstract... } if (!this.implementors.has_key(ch)) { return ret; } foreach(var k in this.implementors.get(ch)) { GLib.debug("add Implementor %s", k); ret.add(k); } return ret; } public Gee.ArrayList possibleParentsOf(string n) { // basically a list of all the types that accept this type, or it's parents.. // find a list of parents. var ret = new Gee.ArrayList(); if (!this.extends.has_key(n)) { return ret; } var ch = this.extends.get(n); foreach(var k in this.childType.keys) { if (ch.contains(this.childType.get(k))) { ret.add(k); } } return ret; } public Gee.ArrayList implementorsOf(string n) { var ret = new Gee.ArrayList(); foreach(var k in this.implementors.get(n)) { ret.add(k); } return ret; } public bool is_a(string cls, string subclass) { return this.extends.get(cls).contains(subclass); } public void dump() { foreach (var k in this.implementors.keys) { GLib.debug("cls: %s : imps: %d", k, this.implementors.get(k).size); } foreach (var k in this.childType.keys) { GLib.debug("cls: %s : child: %s", k, this.childType.get(k)); } foreach (var k in this.extends.keys) { var s = ""; foreach(var v in this.extends.get(k)) { s+=v +", "; } GLib.debug("cls: %s : extends: %s", k,s); } } } public class Flutter : Palete { //public Gee.ArrayList package_cache; static UsageMap usagemap = null; public Flutter(Project.Flutter project) { base(project); this.name = "Flutter"; //var context = new Vala.CodeContext (); //this.package_cache = this.loadPackages(Path.get_dirname (context.get_vapi_path("glib-2.0"))); //this.package_cache.add_all( // this.loadPackages(Path.get_dirname (context.get_vapi_path("gee-0.8"))) //); //this.load(); // various loader methods.. //this.map = []; //this.load(); //this.proplist = {}; //this.comments = { }; if (Flutter.usagemap == null) { Flutter.usagemap = new UsageMap(); } // no parent... } public override void load () { // in Roo & Gtk, usage is loaded here.. but it;s already called in the Ctor.?? //GLib.error("should not get here?"); } public override GirObject? getClass(string ename) { GLib.error("not supported"); return null; } public override Gee.HashMap getPropertiesFor( string ename, string type) { GLib.error("not supported"); return new Gee.HashMap(); } public override void fillPack(JsRender.Node node,JsRender.Node parent) { return; // flutter does not have pack... } public override bool typeOptions(string fqn, string key, string type, out string[] opts) { GLib.error("not supported"); opts = {}; return false; } public override List suggestComplete( JsRender.JsRender file, JsRender.Node? node, string proptype, string key, string complete_string ) { return new List(); } Gee.HashMap> implementors; void loadFlutterUsageFile() { this.usagemap = new UsageMap(); } public override string[] getChildList(string in_rval) { GLib.debug("getChildlist %s", in_rval); // for top level: // StatelessWidget (or a generic 'statefull_myname extends State') //both have a single child that is a widget if (in_rval == "*top") { return { "widgets.StatelessWidget" , "widgets.StatefullWidget" }; } Gee.ArrayList ar = new Gee.ArrayList(); if (in_rval == "widgets.StatelessWidget" || in_rval == "widgets.StatefullWidget") { ar = this.usagemap.implementorsOf("widgets.Widget"); } else { ar = this.usagemap.possibleChildrenOf(in_rval); } string[] ret = {}; foreach(var k in ar) { ret += k; } return ret; } public override string[] getDropList(string rval) { var ar = this.usagemap.possibleParentsOf(rval); if (this.usagemap.is_a(rval, "widgets.Widget")) { ar.add("widgets.StatelessWidget"); ar.add( "widgets.StatefullWidget"); } string[] ret = {}; foreach(var k in ar) { ret += k; } return ret; } public void dumpusage() { this.usagemap.dump(); } } }