Fix #8003 - undo code
[roobuilder] / src / JsRender / NodeToValaExtended.vala
1 /*
2
3 This coverts nodes to vala code (but unlike the original) does it by extending the original wrapped class
4
5 */
6
7 public class  JsRender.NodeToValaExtended : NodeToVala {
8
9          
10          
11  
12         /* 
13          * ctor - just initializes things
14          * - wraps a render node 
15          */
16         public NodeToValaExtended( JsRender file,  Node node,  int depth, NodeToValaExtended? parent) 
17         {
18                 base (file, node, depth, parent);
19                 this.this_el = "this.";
20         }
21         /**
22          *  Main entry point to convert a file into a string..
23          */
24         public static string mungeFile(JsRender file) 
25         {
26                 if (file.tree == null) {
27                         return "";
28                 }
29
30                 var n = new NodeToValaExtended(file, file.tree, 0, null);
31                 n.toValaName(file.tree);
32                 
33                 
34                 GLib.debug("top cls %s / xlcs %s\n ",file.tree.xvala_cls,file.tree.xvala_cls); 
35                                 n.initCls();
36                 return n.munge();
37                 
38
39         }
40         int child_count = 1; // used to number the children.
41         public override string munge ( )
42         {
43                 //return this.mungeToString(this.node);
44                 
45                 if (this.node.as_source_version > 0 && 
46                         this.node.as_source_version == this.node.updated_count
47                         && this.node.as_source != ""
48                 ) {
49                         return this.node.as_source;
50                 }
51                 this.child_count = 1;
52          
53                 
54                 this.namespaceHeader();
55
56                 this.classHeader();
57
58                 this.addTopProperties(); /// properties set with 'id'
59                 this.addMyVars(); // user defined properties.
60                 
61                 // skip '+' properties?? not sure where they are used.
62                 this.addValaCtor();
63  
64                  
65                 this.addInitMyVars();
66                 this.addWrappedProperties();
67                 this.addChildren(); // to constructor code
68                 //this.addSealedChildren();
69                 //this.addAutoShow(); // not needed gtk4 autoshow menuitems
70                 
71                 this.addInit();
72                 this.addListeners();
73                 this.addEndCtor();
74                 this.addUserMethods();
75                 this.iterChildren(); // add children class definitions.
76                 this.namespaceFooter();
77                 
78                 this.node.as_source_version = this.node.updated_count;
79                 this.node.as_source == this.ret;
80                 return this.ret;
81                  
82                          
83         } 
84         
85         public override string mungeChild(  Node cnode)
86         {
87                 var x = new  NodeToValaExtended(this.file, cnode,  this.depth+1, this);
88                 return x.munge();
89         }
90         
91         
92         protected override void classHeader()
93         {
94                            
95                 var top = this.top as NodeToVala;
96                 if (top == null) {
97                         return;
98                 }
99                 // class header..
100                 // class xxx {   WrappedGtk  el; }
101                 this.node.line_start = this.cur_line;
102                 
103                 this.top.node.setNodeLine(this.cur_line, this.node);
104                 
105                 this.addLine(this.inpad + "public class " + this.xcls + " : " + this.cls);
106                 this.addLine(this.inpad + "{");
107                 
108                 this.addLine(this.pad + "private " + top.xcls + "  _this;"); /// or protected??
109                 this.addLine();
110                         
111                         
112                         
113                         // singleton
114         }
115         
116         /**
117          * add the constructor definition..
118          * this probably has to match the parent constructor.. 
119          **?? NO SUPPORT FOR * ARGS?
120          ** for child elements we have to add '_owner to the ctor arguments.
121          for most elements we have to call object ( a: a, b: b)  if the parent requires properties..
122          eg. like Gtk.Box
123          
124          
125          */
126          
127         protected override void addValaCtor()
128         {
129                         
130                 
131                 
132                 var ncls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
133                 if (ncls == null || ncls.nodetype != "Class") { 
134                         this.addLine(this.ipad + "** classname is invalid - can not make ctor "  + this.node.fqn());
135                         return;
136                 }
137                 var ctor = ".new";
138                 var default_ctor = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn() + ctor);              
139                 
140                 if (default_ctor == null) {
141                         this.addLine(this.ipad + "** classname is invalid - can not find ctor "  + this.node.fqn() + ".new");
142                         return;
143                 }
144                 // simple ctor...(will not need ctor params..
145                 
146                 
147                 // now we can skip ctor arguments if we have actually set them?
148                 string[] args  = {};
149                 if (default_ctor.paramset != null &&  default_ctor.paramset.params.size > 0)  {
150                         foreach(var param in default_ctor.paramset.params) {
151                                          
152                                 var n = param.name;
153                                 GLib.debug("building CTOR ARGS: %s, %s", n, param.is_varargs ? "VARARGS": "");
154                                 // not sure if it's even worth warning on this...
155                                 if (n == "___") { // for some reason our varargs are converted to '___' ...
156                                         continue;
157                                 }
158                                 if (this.node.has(n)) {
159                                         continue;
160                                 }
161                                 var propnode = this.node.findProp(n);
162                                 if (propnode != null) {
163                                         continue;
164                                 }
165                                 // finally      
166                                 args += (param.type + " " + n);
167                                   
168
169                         }
170                 }
171                 // create the ctor method
172                 
173  
174                 if (this.depth < 1) {
175                  
176                         // top level - does not pass the top level element..
177                         this.addLine(this.pad + "public " + this.xcls + "()");
178                         this.addLine(this.pad + "{");
179                            
180                 } else {
181                         var top = this.top as NodeToVala;
182                         var tcls = top == null ? "???" : top.xcls;
183                         args += (tcls + " _owner" );
184                                 // for sub classes = we passs the top level as _owner
185                         this.addLine(this.pad + "public " + this.xcls + "(" +  tcls + " _owner )");
186                         this.addLine(this.pad + "{");   
187                          
188                 }
189                 this.addUnderThis(); // set up '_this = _owner or _this = this;
190                 
191                 // if there are no ctor args, then we do not need to call object // or create props.
192                 if (default_ctor.paramset == null ||  default_ctor.paramset.params.size < 1)  {
193                         return;
194                 }
195                 // .vala props.. 
196                 var obj_args = new Gee.HashMap<string,string>();
197                 foreach(var param in default_ctor.paramset.params) {
198                         var n = param.name;
199                         if (n == "___") { // for some reason our varargs are converted to '___' ...
200                                         continue;
201                         }
202                         if (this.node.has(n)) {  // node does not have a value
203                                 
204                                 this.ignoreWrapped(n);
205                                 this.ignore(n);
206                                 
207                                 var v = this.node.get(n);
208
209                                 if (param.type == "string") {
210                                         v = "\"" +  v.escape("") + "\"";
211                                 }
212                                 if (v == "TRUE" || v == "FALSE") {
213                                         v = v.down();
214                                 }
215                                 obj_args.set(n, v);
216                                  
217                                 continue;
218                         }
219                         var propnode = this.node.findProp(n);
220                         if (propnode != null) {
221                                 // assume it's ok..
222                                 
223                                 var pname = this.addPropSet(propnode, propnode.has("id") ? propnode.get_prop("id").val : "");
224                                 obj_args.set(n, pname);
225                                  
226                                 if (!propnode.has("id")) {
227                                         this.addLine(this.ipad + pname +".ref();"); 
228                                 }
229                                  
230                                 this.ignoreWrapped(n); //??? not sure why we dont ignore it as well. 
231                                  
232                                 continue;
233                         }
234                 }
235                 if (obj_args.keys.size < 1) {
236                         return;
237                 }
238                 this.addLine(this.ipad + "Object(");
239                 // at this point we might have object...
240                 var ks = obj_args.keys.to_array();
241                 for(var i = 0; i < ks.length; i++ ) {
242                         var k = ks[i];
243                         var v = obj_args.get(k);
244                         this.addLine(this.ipad + "\t" + k + ": " + v + (i == (ks.length-1) ? "" : ","));
245                 }
246                 this.addLine(this.ipad + ");");
247
248         }
249         
250         
251          
252         
253 }