fix #7989 - add support for extended classes (partial)
[roobuilder] / src / JsRender / NodeWriter.vala
1
2 namespace JsRender {
3         public abstract class NodeWriter : Object {
4         
5         
6                 protected JsRender file;
7                 protected Node node;
8
9                 protected int depth;
10                 protected string inpad;  // the pad for the class outer
11                 protected string pad;   // the padd for the methods / properties.
12                 protected string ipad;
13                  
14                 protected Gee.ArrayList<Node> top_level_items; // top level items (was vitems)
15                 protected int cur_line;
16                 protected NodeWriter top; 
17                 
18                 public string ret {
19                         get {
20                                 return this.output;
21                         }
22                         private set {
23                                 GLib.error("set called on nodewriter ret");
24                         }
25                 }
26          
27                 string output = "";  // the result of outputing..
28                 
29                 Gee.ArrayList<string> ignoreList;
30                 static  Gee.ArrayList<string>? globalIgnoreList = null; 
31                 static construct {
32                         globalIgnoreList = new Gee.ArrayList<string>();
33                 }
34                  
35                 /* 
36                  * ctor - just initializes things
37                  * - wraps a render node 
38                  */
39                 protected NodeWriter( JsRender file,  Node node,  int depth, NodeWriter? parent) 
40                 {
41                         this.file = file;
42                         this.node = node;
43                         this.depth = depth;
44                         if (parent == null) {
45                                 this.var_name_count = 0;
46                         }
47                         this.top_level_items = new Gee.ArrayList<Node>();
48                         this.cur_line = parent == null ? 0 : parent.cur_line;
49                         this.top = parent == null ? this : parent.top;
50                          
51                 // initialize line data..
52                         node.line_start = this.cur_line;
53                         node.line_end  = this.cur_line;
54                         node.lines = new Gee.ArrayList<int>();
55                         node.line_map = new Gee.HashMap<int,string>();
56                         if (parent == null) {
57                                 node.node_lines = new Gee.ArrayList<int>();
58                                 node.node_lines_map = new Gee.HashMap<int,Node>();
59                          }
60                          
61                         this.ignoreList = new Gee.ArrayList<string>();
62                         
63                 }
64                 
65                 int var_name_count = 0; // was vcnt
66
67                 string toValaNS(Node item)
68                 {
69                         return item.get("xns") + ".";
70                 }
71                 /**
72                         fills in all the xvala_cls names into the nodes
73                         
74                 */
75                 
76                 
77                 public void initPadding(char pad, int len) 
78                 {
79                 
80                         var has_ns = this.file.xtype == "Gtk" &&  this.file.file_namespace.length > 0;
81                         
82                         if (has_ns) { // namespaced..
83                                 this.inpad = string.nfill((depth > 0 ? 2 : 1)* len, pad);
84                         } else {
85                                 this.inpad = string.nfill((depth > 0 ? 1 : 0) * len , pad);
86                         }
87                         this.pad = this.inpad + string.nfill(len, pad);
88                         this.node.node_pad = this.inpad;
89                         this.ipad = this.inpad +  string.nfill(2* len, pad);;
90                 
91                 
92                 }
93                 
94                 public void  toValaName(Node item, int depth =0) 
95                 {
96                         this.var_name_count++;
97
98                         var ns =  this.toValaNS(item) ;
99                         var cls = ns + item.get("xtype");
100                         
101                         item.xvala_cls = cls;
102                         
103                         string id = item.get("id").length > 0 ?
104                                 item.get("id") :  "%s%d".printf(item.get("xtype"), this.var_name_count);
105
106                         
107                         
108                         
109                         if (id[0] == '*' || id[0] == '+') {
110                                 item.xvala_xcls = "Xcls_" + id.substring(1);
111                         } else {
112                                 item.xvala_xcls = "Xcls_" + id;
113                         }
114                                 
115                         
116                         item.xvala_id =  id;
117                         if (depth > 0) {                        
118                                 this.top_level_items.add(item);
119                                 
120                         // setting id on top level class changes it classname..                 
121                         // oddly enough we havent really thought about namespacing here.
122                         
123                         } else if (!item.props.has_key("id")) { 
124                                 // use the file name..
125                                 item.xvala_xcls =  this.file.file_without_namespace;
126                                 // is id used?
127                                 item.xvala_id = this.file.file_without_namespace;
128
129                         }
130                                 // loop children..
131                                                                                                                                    
132                         if (item.readItems().size < 1) {
133                                 return;
134                         }
135                         for(var i =0;i<item.readItems().size;i++) {
136                                 this.toValaName(item.readItems().get(i), depth+1);
137                         }
138                                                   
139                 }
140                 
141                 protected void addLine(string str= "")
142                 {
143                         
144                         if (str.contains("\n")) {
145                                 this.addMultiLine(str);
146                                 return;
147                         }
148                         //GLib.debug(str);
149                         this.cur_line++;
150                         //if (BuilderApplication.opt_bjs_compile != null) {
151                         //      this.output += "/*%d*/ ".printf(this.cur_line) + str + "\n";
152                         //} else {
153                                 this.output += str + "\n";
154                         //}
155                 }
156                 protected void addMultiLine(string str= "")
157                 {
158                          
159                         this.cur_line += str.split("\n").length;
160                         //this.ret +=  "/*%d*/ ".printf(l) + str + "\n";
161                         //GLib.debug(str);
162                         this.output +=   str + "\n";
163                 }
164                 protected string padMultiline(string pad, string str)
165                 {
166                         var ar = str.strip().split("\n");
167                         return string.joinv("\n" + pad , ar);
168                 }
169                 protected static void globalIgnore(string i) {
170                         if (globalIgnoreList == null) {
171                                 globalIgnoreList =  new Gee.ArrayList<string>(); // should not happend.. but dont know about ctor process..
172                         }
173                         globalIgnoreList.add(i);
174                 }
175                 
176                 protected void ignore(string i) {
177                         this.ignoreList.add(i);
178                         
179                 }
180                 
181                 protected bool shouldIgnore(string i)
182                 {
183                         return globalIgnoreList.contains(i) || ignoreList.contains(i);
184                 }
185                 
186                 
187                 // interface
188                 public abstract string munge();
189                 
190                 
191                 
192         }
193 }