Fix #5829 - Messing around with flutter API
[roobuilder] / src / Palete / Flutter.vala
1 using Gtk;
2  
3 namespace Palete {
4
5
6         public class UsageMap : Object
7         {
8                 Gee.HashMap<string,Gee.ArrayList<string>> implementors;
9                 Gee.HashMap<string,string> childType;
10                 Gee.HashMap<string,int> no_children;
11                 Gee.HashMap<string,bool> is_abstract;
12             Gee.HashMap<string,Gee.ArrayList<string>> extends;
13             
14                 public UsageMap() 
15                 {
16                         this.implementors = new Gee.HashMap<string,Gee.ArrayList<string>>();
17                         this.extends = new Gee.HashMap<string,Gee.ArrayList<string>>();
18                         this.childType = new Gee.HashMap<string,string>();
19                         this.no_children = new Gee.HashMap<string,int>();
20                         this.is_abstract = new Gee.HashMap<string,bool>();                      
21                         var pa = new Json.Parser();
22                         pa.load_from_file(BuilderApplication.configDirectory() + "/resources/flutter_tree.json");
23
24                         var node = pa.get_root();
25                         this.addArray(node.get_array());
26                         
27                         this.removeNonChild();
28                 } 
29                 
30
31                 private void addArray(Json.Array ar)
32                 {
33                         for(var i=0;i< ar.get_length();  i++) {
34                                 this.addObject(ar.get_object_element(i));
35                         }
36                 }
37                 private void addObject(Json.Object o)
38                 {
39                         
40                         this.addArray(o.get_array_member("cn"));
41                         
42                         var name = o.get_string_member("name");
43                         if (!o.get_boolean_member("is_class")) {
44                                 return;
45                         }
46                         if (o.get_array_member("implementors").get_length() > 0) {
47                                 this.implementors.set(name , this.jsonStringArray(o.get_array_member("implementors")));
48                         }
49                         if (o.get_array_member("extends").get_length() > 0) {
50                                 this.extends.set(name , this.jsonStringArray(o.get_array_member("extends")));
51                         }                       
52                         if (o.get_string_member("childtype").length > 0) {
53                                 this.childType.set( name, o.get_string_member("childtype"));
54                                 this.no_children.set( name, (int) o.get_int_member("childtypes"));
55                         }
56                         
57                 }
58                 private  Gee.ArrayList<string> jsonStringArray(Json.Array ar)
59                 {
60                         var ret = new Gee.ArrayList<string>();
61                         for(var i=0;i< ar.get_length();  i++)  {
62                                 ret.add(ar.get_string_element(i));
63                         }
64                         return ret;
65                 }
66                 public void removeNonChild()
67                 {
68                         // do we need to clean this up?
69                         // remove all the unrelated objects?
70                 }
71                 public Gee.ArrayList<string> possibleChildrenOf(string n)
72                 {
73                         GLib.debug("possibleChildrenOf %s", n);
74                         var ret = new Gee.ArrayList<string>();
75                         if (!this.childType.has_key(n)) {
76                                 return ret;
77                         }
78                         
79                         var ch = this.childType.get(n);
80                         GLib.debug("childType %s", ch);
81                         
82                         if (this.is_abstract.has_key(ch)  && !this.is_abstract.get(ch)) {
83                                 GLib.debug("add Implementor (self) %s", ch);                    
84                                 ret.add(ch); // it's not abstract...
85                         }
86
87                         if (!this.implementors.has_key(ch)) {
88                                 return ret;
89                         }
90                         foreach(var k in this.implementors.get(ch)) {
91                                 GLib.debug("add Implementor %s", k);
92                                 ret.add(k);
93                         }
94                         return ret;
95                 }
96                 public Gee.ArrayList<string> possibleParentsOf(string n)
97                 {
98                         
99                         // basically a list of all the types that accept this type, or it's parents..
100                         // find a list of parents.
101                         
102                         var ret = new Gee.ArrayList<string>();
103                         if (!this.extends.has_key(n)) {
104                                 return ret;
105                         }
106                         var ch = this.extends.get(n);
107
108                         foreach(var k in this.childType.keys) {
109                                 if (ch.contains(this.childType.get(k))) {
110                                         ret.add(k);
111                                 }
112                         }
113
114                         return ret;
115                 }
116                 
117                 
118                 public Gee.ArrayList<string> implementorsOf(string n)
119                 {
120                         var ret = new Gee.ArrayList<string>();
121                         foreach(var k in this.implementors.get(n)) {
122                                 ret.add(k);
123                         }
124                         return ret;
125                 }
126                 
127                 public bool is_a(string cls, string subclass) {
128                         return this.extends.get(cls).contains(subclass);
129                 }
130                 
131                 public void dump()
132                 {
133                         foreach (var k  in this.implementors.keys) {
134                                 GLib.debug("cls: %s : imps: %d", k, this.implementors.get(k).size);
135                         }
136                         foreach (var k  in this.childType.keys) {
137                                 GLib.debug("cls: %s : child: %s", k, this.childType.get(k));
138                         }
139                         foreach (var k  in this.extends.keys) {
140                                 var s = "";
141                                 foreach(var v in this.extends.get(k)) {
142                                         s+=v +", ";
143                                 }
144                                 GLib.debug("cls: %s : extends: %s", k,s);
145                         }
146                 }
147                 
148         }
149
150
151         public class Flutter : Palete {
152                 
153                 //public Gee.ArrayList<string> package_cache;
154                 static UsageMap usagemap = null;
155                 
156                 public Flutter(Project.Flutter project)
157                 {
158                          base(project);
159                     this.name = "Flutter";
160                     //var context = new Vala.CodeContext ();
161                          
162                     //this.package_cache = this.loadPackages(Path.get_dirname (context.get_vapi_path("glib-2.0")));
163                     //this.package_cache.add_all(
164                          //   this.loadPackages(Path.get_dirname (context.get_vapi_path("gee-0.8")))
165                     //);
166                                 //this.load();
167                     // various loader methods..
168                       //this.map = [];
169                     //this.load();
170                     //this.proplist = {};
171                     //this.comments = { }; 
172                     if (Flutter.usagemap == null) {
173                         Flutter.usagemap = new UsageMap();
174                 }
175                     // no parent...
176                 }
177                 public override void  load () {
178                         // in Roo & Gtk, usage is loaded here.. but it;s already called in the Ctor.??
179                         //GLib.error("should not get here?");
180                 }
181                 
182                 public override GirObject? getClass(string ename)
183                 {
184
185                         GLib.error("not supported");
186                  
187                         return null;
188                 
189                 }
190                 public override Gee.HashMap<string,GirObject> getPropertiesFor( string ename, string type)  
191                 {
192                 
193                         GLib.error("not supported");
194                 
195                         return new Gee.HashMap<string,GirObject>();
196                 }
197                 
198                 public override void fillPack(JsRender.Node node,JsRender.Node parent)
199                 {   
200                         return; // flutter does not have pack...
201                 }
202                 public override bool  typeOptions(string fqn, string key, string type, out string[] opts) 
203                 {
204                         GLib.error("not supported");
205                         opts = {};
206                         return false;
207                 }
208                 public override  List<SourceCompletionItem> suggestComplete(
209                                 JsRender.JsRender file,
210                                 JsRender.Node? node,
211                                 string proptype, 
212                                 string key,
213                                 string complete_string
214                 ) { 
215                                 return new List<SourceCompletionItem>();
216                 }
217                 Gee.HashMap<string,Gee.ArrayList<string>> implementors;
218                 void loadFlutterUsageFile()
219                 {
220                         this.usagemap = new UsageMap();
221                 }
222                 
223                 public override string[] getChildList(string in_rval)
224                 {
225                         GLib.debug("getChildlist %s", in_rval);
226                          // for top level:
227                          // StatelessWidget  (or a generic 'statefull_myname extends State<myname>')
228                          //both have a single child that is a widget
229                         if (in_rval == "*top") {
230                                 return { "widgets.StatelessWidget" , "widgets.StatefullWidget" };
231                         }
232                         Gee.ArrayList<string> ar = new Gee.ArrayList<string>();
233                         if (in_rval == "widgets.StatelessWidget" || in_rval == "widgets.StatefullWidget") {
234                                 ar = this.usagemap.implementorsOf("widgets.Widget");
235                         } else {
236                                 
237                                 ar = this.usagemap.possibleChildrenOf(in_rval);
238                         }
239                          string[] ret = {};
240                          foreach(var k in ar) {
241                                 ret += k;
242                          }
243                          return ret;
244                         
245                 }
246                 public override string[] getDropList(string rval)
247                 {
248                         var ar =  this.usagemap.possibleParentsOf(rval);
249                         if (this.usagemap.is_a(rval,   "widgets.Widget")) {
250                                 ar.add("widgets.StatelessWidget");
251                                 ar.add( "widgets.StatefullWidget");
252                         }
253                         
254                         string[] ret = {};
255                          foreach(var k in ar) {
256                                 ret += k;
257                          }
258                          return ret;
259  
260                 }       
261                 
262                 public void dumpusage()
263                 {
264                         this.usagemap.dump();
265                 
266                 }
267          
268                 
269         }
270 }