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