bd74fe123a3b9cfeb6143402e5ba3bd4e3d24623
[roobuilder] / src / JsRender / NodeToVala.vala
1 /**
2  * 
3  * Code to convert node tree to Vala...
4  * 
5  * usage : x = (new JsRender.NodeToVala(node)).munge();
6  * 
7  * Fixmes?
8  *
9  *  pack - can we come up with a replacement?
10      - parent.child == child_widget -- actually uses getters and effectively does 'add'?
11        (works on most)?
12     
13      
14  * args  -- vala constructor args (should really only be used at top level - we did use it for clutter originally(
15  * ctor  -- different ctor argument
16  
17  * 
18  
19  * 
20  * 
21 */
22
23  
24 public abstract class JsRender.NodeToVala : NodeWriter {
25
26         protected string this_el = "??";
27          
28         int child_count = 1; // used to number the children.
29         public string cls;  // node fqn()
30         public string xcls;
31         
32
33         Gee.ArrayList<string> ignoreWrappedList; 
34         Gee.ArrayList<string> myvars;
35
36
37          
38         int pane_number = 0;// ?? used when generating Gtk.Pane tabs
39         
40         
41         static construct {
42                 NodeWriter.globalIgnore("pack");
43                 NodeWriter.globalIgnore("init");
44                 NodeWriter.globalIgnore("xns");
45                 NodeWriter.globalIgnore("xtype");
46                 NodeWriter.globalIgnore("id");
47         
48         }
49         /* 
50          * ctor - just initializes things
51          * - wraps a render node 
52          */
53         protected NodeToVala( JsRender file,  Node node,  int depth, NodeToVala? parent) 
54         {
55
56                 base (file, node, depth, parent);
57          
58                 this.initPadding('\t', 1);
59                 
60                 this.cls = node.xvala_cls;
61                 this.xcls = node.xvala_xcls;
62                 if (depth == 0 && this.xcls.contains(".")) {
63                         var ar = this.xcls.split(".");
64                         this.xcls = ar[ar.length-1];
65                 }
66                 
67
68                 this.ignoreWrappedList  = new Gee.ArrayList<string>();
69                 this.myvars = new Gee.ArrayList<string>();
70                 this.child_count = 1;
71                  
72         }
73  
74         public void initCls()
75         {
76                 this.cls = this.file.tree.xvala_cls;
77                 this.xcls = this.file.tree.xvala_xcls;
78         }
79         public abstract  string mungeChild(  Node cnode);
80         
81          
82         public void namespaceHeader()
83         {
84                 if (this.depth > 0 || this.file.file_namespace == "") {
85                         return;
86                 } 
87                 this.addLine("namespace " + this.file.file_namespace);
88                 this.addLine("{");
89         
90         }
91         public void namespaceFooter()
92         {
93                 if (this.depth > 0 || this.file.file_namespace == "") {
94                         return;
95                 }
96                 this.addLine("}");
97         
98         }
99         
100
101         protected abstract void classHeader();
102          
103
104                         
105         /**
106          * when ID is used... on an element, it registeres a property on the top level...
107          * so that _this.ID always works..
108          * 
109          */
110         protected void addTopProperties()
111         {
112                 if (this.depth > 0) {
113                         return;
114                 }
115                 // properties - global..??
116                 foreach(var n in this.top_level_items) { 
117
118                         if (!n.props.has_key("id") || n.xvala_id.length < 0) {
119                                 continue;
120                                 
121                         }
122                         if (n.xvala_id[0] == '*' || n.xvala_id[0] == '+') {
123                                 continue;
124                         }
125                          
126                         this.addLine(this.pad + "public " + n.xvala_xcls + " " + n.xvala_id + ";");
127                         
128                 }
129                                 
130         }
131         /**
132          * create properties that are not 'part of the wrapped element.
133          * 
134          * 
135          */
136  
137         protected void addMyVars()
138         {
139                 GLib.debug("callinged addMhyVars");
140                 
141                 this.addLine();
142                 this.addLine(this.ipad + "// my vars (def)");
143                         
144
145  
146                 var cls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
147                    
148                 if (cls == null) {
149                         GLib.debug("Gir factory failed to find class %s", this.node.fqn());
150                         
151                         //return;
152                 }
153           
154                 
155                         // Key = TYPE:name
156                 foreach(var prop in this.node.props.values) {
157                    
158                         if (this.shouldIgnore(prop.name)) {
159                                 continue;
160                         }
161
162                         // user defined method
163                         if (prop.ptype == NodePropType.METHOD) {
164                                 continue;
165                         }
166                         if (prop.ptype == NodePropType.SPECIAL) {
167                                 continue;
168                         }
169                                 
170                         if (prop.ptype == NodePropType.SIGNAL) {
171                                 this.node.setLine(this.cur_line, "p", prop.name);
172                                 this.addLine(this.pad + "public signal " + prop.rtype + " " + prop.name  + " "  + prop.val + ";");
173                                 
174                                 this.ignore(prop.name);
175                                 continue;
176                         }
177                         
178                         GLib.debug("Got myvars: %s", prop.name.strip());
179                         
180                         if (prop.rtype.strip().length < 1) {
181                                 continue;
182                         }
183                         
184                         // is it a class property...
185                         if (cls != null && cls.props.has_key(prop.name) && prop.ptype != NodePropType.USER) {
186                                 continue;
187                         }
188                         
189                         this.myvars.add(prop.name);
190                         prop.start_line = this.cur_line;
191                         
192                         this.node.setLine(this.cur_line, "p", prop.name);
193                         
194                         this.addLine(this.pad + "public " + prop.rtype + " " + prop.name + ";"); // definer - does not include value.
195
196
197                         prop.end_line = this.cur_line;                          
198                         this.ignore(prop.name);
199                         
200                                 
201                 }
202         }
203         
204         // if id of child is '+' then it's a property of this..
205         protected void addPlusProperties()
206         {
207                 if (this.node.readItems().size < 1) {
208                         return;
209                 }
210                 var iter = this.node.readItems().list_iterator();
211                 while (iter.next()) {
212                         var ci = iter.get();
213                                 
214                         if (ci.xvala_id[0] != '+') {
215                                 continue; // skip generation of children?
216                                 
217                         }
218                          
219                         this.addLine(this.pad + "public " + ci.xvala_xcls + " " + ci.xvala_id.substring(1) + ";");
220                                            
221                         
222                 }
223         }
224         /**
225          * add the constructor definition..
226          */
227         protected abstract void addValaCtor();
228         /**
229          *  make sure _this is defined..
230          */
231         protected void addUnderThis() 
232         {
233                 // public static?
234                 if (depth < 1) {
235                         this.addLine( this.ipad + "_this = this;");
236                         return;
237                 }
238                 // for non top level = _this point to owner, and _this.ID is set
239                 
240                 this.addLine( this.ipad + "_this = _owner;");
241
242                 if (this.node.props.has_key("id")
243                         &&
244                         this.node.xvala_id != "" 
245                         && 
246                         this.node.xvala_id[0] != '*' 
247                         && 
248                         this.node.xvala_id[0] != '+' 
249                         ) {
250                                 this.addLine( this.ipad + "_this." + node.xvala_id  + " = this;");
251                    
252                 }
253                          
254         }
255          
256         
257          
258         protected void addInitMyVars()
259         {
260                         //var meths = this.palete.getPropertiesFor(item['|xns'] + '.' + item.xtype, 'methods');
261                         //print(JSON.stringify(meths,null,4));Seed.quit();
262                         
263                         
264                         
265                         // initialize.. my vars..
266                 this.addLine();
267                 this.addLine( this.ipad + "// my vars (dec)");
268                 
269                 var iter = this.myvars.list_iterator();
270                 while(iter.next()) {
271                         
272                         var k = iter.get();
273                         
274                          
275                         var prop = this.node.props.get(k);
276                         
277                         var v = prop.val.strip();                       
278                         
279                         if (v.length < 1) {
280                                 continue; 
281                         }
282                         // at this point start using 
283
284                         if (v == "FALSE" || v == "TRUE") {
285                                 v= v.down();
286                         }
287                         //FIXME -- check for raw string.. "string XXXX"
288                         
289                         // if it's a string...
290                         
291                         prop.start_line = this.cur_line;
292                         this.addLine(this.ipad + "this." + prop.name + " = " +   v +";");
293                         prop.end_line = this.cur_line;
294                 }
295         }
296
297         
298
299
300         
301         protected  void addWrappedProperties()
302         {
303                 var cls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
304                 if (cls == null) {
305                         GLib.debug("Skipping wrapped properties - could not find class  %s" , this.node.fqn());
306                         return;
307                 }
308                         // what are the properties of this class???
309                 this.addLine();
310                 this.addLine(this.ipad + "// set gobject values");
311                 
312                 foreach(var p in cls.props.keys) { 
313                         var val = cls.props.get(p);
314                         //print("Check Write %s\n", p);
315                         if (!this.node.has(p)) {
316                                 continue;
317                         }
318                         if (this.shouldIgnoreWrapped(p)) {
319                                 continue;
320                         }
321                         
322                         this.ignore(p);
323
324
325                         var prop = this.node.get_prop(p);
326                         var v = prop.val;
327                         
328                         // user defined properties.
329                         if (prop.ptype == NodePropType.USER) {
330                                 continue;
331                         }
332                                 
333
334                         
335                         var is_raw = prop.ptype == NodePropType.RAW;
336                         
337                         // what's the type.. - if it's a string.. then we quote it..
338                         if (val.type == "string" && !is_raw) {
339                                  v = "\"" +  v.escape("") + "\"";
340                         }
341                         if (v == "TRUE" || v == "FALSE") {
342                                 v = v.down();
343                         }
344                         if (val.type == "float" && v[v.length-1] != 'f') {
345                                 v += "f";
346                         }
347                         
348                         prop.start_line = this.cur_line;
349                         this.addLine("%s%s%s = %s;".printf(ipad,this.this_el,p,v)); // // %s,  iter.get_value().type);
350
351                         
352                         
353                         prop.end_line = this.cur_line;          
354                            // got a property..
355                            
356
357                 }
358         } 
359         /**
360          *  pack the children into the parent.
361          * 
362          * if the child's id starts with '*' then it is not packed...
363          * - this allows you to define children and add them manually..
364          */
365
366         protected  void addChildren()
367         {
368                                 //code
369                 if (this.node.readItems().size < 1) {
370                         return;
371                 }
372                 this.pane_number = 0;
373                 var cols = this.node.has("* columns") ? int.max(1, int.parse(this.node.get_prop("* columns").val)) : 1;
374                 var colpos = 0;
375                 
376  
377                  
378                 foreach(var child in this.node.readItems()) {
379                         
380                         
381                          
382
383                         if (child.xvala_id[0] == '*') {
384                                 continue; // skip generation of children?
385                         }
386
387                         // probably added in ctor..                             
388                         if (child.has("* prop") && this.shouldIgnoreWrapped(child.get_prop("* prop").val)) {
389                                 continue;
390                         }
391                         // create the element..
392                         
393                         // this is only needed if it does not have an ID???
394                         var childname = this.addPropSet(child, child.has("id") ? child.get_prop("id").val : "") ; 
395                         if (!child.has("id")) {
396                                 // must ref new objects..
397                                 this.addLine("%s%s.ref();".printf(ipad, childname));
398                         }
399                         if (child.has("* prop")) {
400                          
401                         
402                                 // fixme special packing!??!?!
403                                 if (child.get_prop("* prop").val.contains("[]")) {
404                                         // currently these 'child props
405                                         // used for label[]  on Notebook
406                                         // used for button[]  on Dialog?
407                                         // columns[] ?
408                                          
409                                         this.packChild(child, childname, 0, 0, child.get_prop("* prop").val);  /// fixme - this is a bit speciall...
410                                         continue;
411                                 }
412                                 
413         
414                                 
415                                 this.ignoreWrapped(child.get_prop("* prop").val);
416                                 var el_name = this.this_el == "this.el." ? ".el" : "";
417                                 
418                                 
419                                 this.addLine(ipad + this.this_el  + child.get_prop("* prop").val + " = " + childname + el_name +";");
420                                 
421                                 continue;
422                         } 
423                          if (!child.has("id") && this.this_el == "this.el.") {
424                                 this.addLine(this.ipad +  childname +".ref();"); 
425                          } 
426                         this.packChild(child, childname, cols, colpos);
427                         
428                         if (child.has("colspan")) {
429                                 colpos += int.parse(child.get_prop("colspan").val);
430                         } else {
431                                 colpos += 1;
432                         }
433                                           
434                         
435                         // this.{id - without the '+'} = the element...
436                          
437                                   
438                 }
439         }
440         
441         protected string addPropSet(Node child, string child_name) 
442         {
443          
444                 
445                 var xargs = "";
446                 if (child.has("* args")) {
447                         
448                         var ar = child.get_prop("* args").val.split(",");
449                         for (var ari = 0 ; ari < ar.length; ari++ ) {
450                                 var arg = ar[ari].split(" ");
451                                 xargs += "," + arg[arg.length -1];
452                         }
453                 }
454                 
455                 var childname = "child_" + "%d".printf(this.child_count++);     
456                 var prefix = "";
457                 if (child_name == "") {
458                         prefix = "var " + childname + " = ";
459                 }
460                 var cls =  child.xvala_xcls;
461                 /*
462                 if (this.this_el == "this.") {
463                         var clsdata = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
464                         //if (clsdata.is_sealed) {
465                                 cls = this.node.fqn(); // need ctor data...
466                                 this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
467                                 return child_name == "" ? childname : ("_this." + child_name);  
468                         }
469                 }
470                 */
471                 
472                 this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
473                  
474                 // add a ref... (if 'id' is not set... to a '+' ?? what does that mean? - fake ids?
475                 // remove '+' support as I cant remember what it does!!!
476                 //if (child.xvala_id.length < 1 ) {
477                 //      this.addLine(this.ipad + childname +".ref();"); // we need to reference increase unnamed children...
478                 //}                     
479             //if (child.xvala_id[0] == '+') {
480                 //      this.addLine(this.ipad + "this." + child.xvala_id.substring(1) + " = " + childname+  ";");
481                                         
482                 //}
483                 
484
485                 return child_name == "" ? childname : ("_this." + child_name);  
486         }               
487                         
488         
489
490         
491         protected void packChild(Node child, string childname, int cols, int colpos, string propname= "")
492         {
493                 
494                 GLib.debug("packChild %s=>%s", this.node.fqn(), child.fqn());
495                 // forcing no packing? - true or false? -should we just accept false?
496                 if (child.has("* pack") && child.get("* pack").down() == "false") {
497                         return; // force no packing
498                 }
499                 if (child.has("* pack") && child.get("* pack").down() == "true") {
500                         return; // force no packing
501                 }
502                 var el_name = this.this_el == "this.el." ? ".el" : "";
503                 var this_el = this.this_el;
504                 // BC really - don't want to support this anymore.
505                 if (child.has("* pack")) {
506                         
507                         string[]  packing =  { "add" };
508                         if (child.has("* pack")) {
509                                 packing = child.get("* pack").split(",");
510                         }
511                         
512                         var pack = packing[0];
513                         this.addLine(this.ipad + this.this_el + pack.strip() + " ( " + childname + el_name + " " +
514                                    (packing.length > 1 ? 
515                                                 (", " + string.joinv(",", packing).substring(pack.length+1))
516                                         : "" ) + " );");
517                         return;  
518                 }
519                 var childcls =  this.file.project.palete.getClass(child.fqn()); // very trusting..
520                 if (childcls == null) {
521                   return;
522                 }
523                 // GTK4
524                 var is_event = childcls.inherits.contains("Gtk.EventController") || childcls.implements.contains("Gtk.EventController");
525                 if (is_event) {
526                     this.addLine(this.ipad + this.this_el + "add_controller(  %s.el );".printf(childname) );
527                     return;
528                 }
529                 
530                 
531                 switch (this.node.fqn()) {
532                         
533                                 
534                 
535                         case "Gtk.Fixed":
536                         case "Gtk.Layout":
537                                 var x = child.has("x") ?  child.get_prop("x").val  : "0";
538                                 var y = child.has("y") ?  child.get_prop("y").val  : "0";
539                                 this.addLine(@"$(ipad)$(this_el)put( $(childname)$(el_name), $(x), $(y) );");
540                                 return;
541                                 
542                         
543
544                         case "Gtk.Stack":
545                                 var named = child.has("stack_name") ?  child.get_prop("stack_name").val.escape() : "";
546                                 var title = child.has("stack_title") ?  child.get_prop("stack_title").val.escape()  : "";
547                                 if (title.length > 0) {
548                                         this.addLine(@"$(ipad)$(this_el)add_titled( $(childname)$(el_name), \"$(named)\", \"$(title)\" );");
549                                         return;
550                                 } 
551                                 this.addLine(@"$(ipad)$(this_el)add_named( $(childname)$(el_name), \"$(named)\");");
552                                 return;
553                                 
554                         case "Gtk.Notebook": // use label
555                                 var label = child.has("notebook_label") ?  child.get_prop("notebook_label").val.escape() : "";
556                                 this.addLine(@"$(ipad)$(this_el)append_page( $(childname)$(el_name), new Gtk.Label(\"$(label)\");");
557                                 
558                                 return;
559                                 
560                          
561                         case "Gtk.TreeView": // adding TreeViewColumns
562                                 this.addLine(this.ipad + "this.el.append_column( " + childname + ".el );");
563                                 return;
564                         
565                         case "Gtk.TreeViewColumn": //adding Renderers - I think these are all proprerties of the renderer used...
566                                 if (child.has("markup_column") && int.parse(child.get_prop("markup_column").val) > -1) {
567                                         var val = child.get_prop("markup_column").val;
568                                         this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"markup\", $(val) );");
569  
570                                 }
571                                 if (child.has("text_column") && int.parse(child.get_prop("text_column").val) > -1) {
572                                         var val = child.get_prop("text_column").val;
573                                         this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"text\", $(val) );");
574                                 }
575                                 if (child.has("pixbuf_column") && int.parse(child.get_prop("pixbuf_column").val) > -1) {
576                                         var val = child.get_prop("pixbuf_column").val;
577                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"pixbuf\", $(val) );");
578                                 }
579                                 if (child.has("pixbuf_column") && int.parse(child.get_prop("active_column").val) > -1) {
580                                         var val = child.get_prop("active_column").val;
581                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"active\", $(val) );");
582                                 }
583                                 if (child.has("background_column") && int.parse(child.get_prop("background_column").val) > -1) {
584                                 var val = child.get_prop("background_column").val;
585                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"background-rgba\", $(val) );");
586                                 }
587                                 this.addLine(this.ipad + "this.el.add( " + childname + ".el );");
588                                 // any more!?
589                                 return;
590                 
591                         case "Gtk.Dialog":
592                                 if (propname == "buttons[]") {
593                                         var resp_id = int.parse(childname.replace("child_", ""));
594                                         if (child.has("* response_id")) { 
595                                                 resp_id = int.parse(child.get_prop("* response_id").val);
596                                         }
597                                         this.addLine(@"$(ipad)$(this_el).add_action_widget( $(childname)$(el_name), $(resp_id) );");
598
599                                         return;
600                                 }
601                         
602                                 this.addLine(@"$(ipad)$$(this_el)get_content_area().add( $(childname)$(el_name) );");
603                                 return;
604
605                 
606                                 
607                         
608         
609         
610         // known working with GTK4 !
611                         case "Gtk.HeaderBar": // it could be end... - not sure how to hanle that other than overriding                                  this.addLine(this.ipad + "this.el.add_action_widget( %s.el, %d);".printf(childname,resp_id) ); the pack method?
612                                 this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
613                                 return;
614                         
615                         case "GLib.Menu":
616                                 this.addLine(@"$(ipad)$(this_el)append_item( $(childname)$(el_name) );");
617                                 return; 
618                         
619                         case "Gtk.Paned":
620                                 this.pane_number++;
621                                 switch(this.pane_number) {
622                                         case 1:
623                                                 this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
624                                                 return;
625                                         case 2: 
626                                                 this.addLine(@"$(ipad)$(this_el)pack_end( $(childname)$(el_name) );");
627                                                 return;
628                                         default:
629                                                 // do nothing
630                                                 break;
631                                 }
632                                 return;
633                         
634                         case "Gtk.ColumnView":
635                                 this.addLine(@"$(ipad)$(this_el)append_column( $(childname)$(el_name) );");
636                                 return;
637                         
638                         case "Gtk.Grid":
639                                 var x = "%d".printf(colpos % cols);
640                                 var y = "%d".printf(( colpos - (colpos % cols) ) / cols);
641                                 var w = child.has("colspan") ? child.get_prop("colspan").val : "1";
642                                 var h = "1";
643                                 this.addLine(@"$(ipad)$(this_el)attach( $(childname)$(el_name), $x, $y, $w, $h );");
644                                 return;
645                         
646                         default:
647                                 this.addLine(@"$(ipad)$(this_el)append( $(childname)$(el_name) );");
648                             // gtk4 uses append!!!! - gtk3 - uses add..
649                                 return;
650                 
651                 
652                 }
653                 
654                 
655         }
656         
657         // fixme GtkDialog?!? buttons[]
658         
659         // fixme ... add case "Gtk.RadioButton":  // group_id ??
660
661                         
662
663         protected void addInit()
664         {
665
666                 
667                 if (!this.node.has("* init")) {
668                                 return;
669                 }
670                 this.addLine();
671                 this.addLine(ipad + "// init method");
672                 this.addLine();
673                 this.node.setLine(this.cur_line, "p", "init");
674                 
675                 var init =  this.node.get_prop("* init");
676                 init.start_line = this.cur_line;
677                 this.addMultiLine(ipad + this.padMultiline(ipad, init.val) );
678                 init.end_line = this.cur_line;
679          }
680          protected void addListeners()
681          {
682                 if (this.node.listeners.size < 1) {
683                         return;
684                 }
685                                 
686                 this.addLine();
687                 this.addLine(ipad + "//listeners");
688                         
689                          
690
691                 var iter = this.node.listeners.map_iterator();
692                 while (iter.next()) {
693                         var k = iter.get_key();
694                         var prop = iter.get_value();
695                         var v = prop.val;
696                         
697                         prop.start_line = this.cur_line;
698                         this.node.setLine(this.cur_line, "l", k);
699                         this.addMultiLine(this.ipad + this.this_el + k + ".connect( " + 
700                                         this.padMultiline(this.ipad,v) +");"); 
701                         prop.end_line = this.cur_line;
702                 }
703         }    
704         protected void addEndCtor()
705         {
706                          
707                         // end ctor..
708                         this.addLine(this.pad + "}");
709         }
710
711
712         /*
713  * Standardize this crap...
714  * 
715  * standard properties (use to set)
716  *          If they are long values show the dialog..
717  *
718  * someprop : ....
719  * bool is_xxx  :: can show a pulldown.. (true/false)
720  * string html  
721  * $ string html  = string with value interpolated eg. baseURL + ".." 
722  *  Clutter.ActorAlign x_align  (typed)  -- shows pulldowns if type is ENUM? 
723  * $ untypedvalue = javascript untyped value...  
724  * _ string html ... = translatable..
725
726  * 
727  * object properties (not part of the GOjbect being wrapped?
728  * # Gee.ArrayList<Xcls_fileitem> fileitems
729  * 
730  * signals
731  * @ void open 
732  * 
733  * methods -- always text editor..
734  * | void clearFiles
735  * | someJSmethod
736  * 
737  * specials
738  * * prop -- string
739  * * args  -- string
740  * * ctor -- string
741  * * init -- big string?
742  * 
743  * event handlers (listeners)
744  *   just shown 
745  * 
746  * -----------------
747  * special ID values
748  *  +XXXX -- indicates it's a instance property / not glob...
749  *  *XXXX -- skip writing glob property (used as classes that can be created...)
750  * 
751  * 
752  */
753          
754         protected void addUserMethods()
755         {
756                 this.addLine();
757                 this.addLine(this.pad + "// user defined functions");
758                         
759                         // user defined functions...
760                 var iter = this.node.props.map_iterator();
761                 while(iter.next()) {
762                         var prop = iter.get_value();
763                         if (this.shouldIgnore(prop.name)) {
764                                 continue;
765                         }
766                         // HOW TO DETERIME if its a method?            
767                         if (prop.ptype != NodePropType.METHOD) {
768                                         //strbuilder("\n" + pad + "// skip " + k + " - not pipe \n"); 
769                                         continue;
770                         }
771                         
772                         // function in the format of {type} (args) { .... }
773
774
775
776                         prop.start_line = this.cur_line;
777                         this.node.setLine(this.cur_line, "p", prop.name);
778                         this.addMultiLine(this.pad + "public " + prop.rtype + " " +  prop.name + " " + this.padMultiline(this.pad, prop.val));;
779                         prop.end_line = this.cur_line;
780                                 
781                 }
782         }
783
784         protected void iterChildren()
785         {
786                 this.node.line_end = this.cur_line;
787                 this.node.sortLines();
788                 
789                         
790                 if (this.depth > 0) {
791                         this.addLine(this.inpad + "}");
792                 }
793                 
794                 var iter = this.node.readItems().list_iterator();
795                  
796                 while (iter.next()) {
797                         this.addMultiLine(this.mungeChild(iter.get()));
798                 }
799                          
800                 if (this.depth < 1) {
801                         this.addLine(this.inpad + "}");
802                 }
803                         
804         }
805  
806
807         
808         protected void ignoreWrapped(string i) {
809                 this.ignoreWrappedList.add(i);
810                 
811         }
812         
813         protected  bool shouldIgnoreWrapped(string i)
814         {
815                 return ignoreWrappedList.contains(i);
816         }
817         
818 }
819         
820          
821         
822