JSDOC/CompressWhite.vala
[gnome.introspection-doc-generator] / JSDOC / Collapse.vala
1
2 /**
3  * 
4  * base class for parsing segments of token array..
5  * 
6  * 
7  * We want to make parsing the whole thing easy..
8  * 
9  * so we do various tricks:
10  * 
11  * 
12  * a) white space collased
13  *    wsPrefix 
14  * b)  toks
15  *     { } - collapse into first element.
16        ( ) - collapse into first element.
17        [ ] - collapse into first element.
18  * c) items = , seperation within the above..
19  * 
20  * usage: x = new Collapse(token_array)
21  * 
22  * 
23  * 
24  * 
25  */ 
26
27 namespace JSDOC {
28
29         public class  Collapse : TokenStream  {
30
31
32
33
34                 public Collapse(Gee.ArrayList<Token> tokens) 
35                 {
36                     base(tokens);
37                     
38                     this.spaces();
39                     
40                     var ar = this.collapse(this.tokens);
41                     
42                     this.tokens = ar;
43                     
44                    // console.dump(ar);
45                     
46                 }
47                 
48                 // put spaces into prefix of tokens..
49     
50         void spaces () 
51         {
52             var ar = new Gee.ArrayList<Token>();
53             var pref =  new Gee.ArrayList<Token>();
54             
55                         
56             
57             for (var i = 0; i < this.tokens.size; i ++) {
58                 var tok = this.tokens[i];
59                 if (tok.is("COMM") || tok.is("WHIT")) {
60                     pref.add(tok);
61                     continue;
62                 }
63                 tok.prefix = "";
64                 if (pref.size > 0) {
65                         foreach(var e in pref) {
66                         tok.prefix += e.data;
67                     }
68                     pref =  new Gee.ArrayList<Token>(); // reset pref..
69                 }
70                 
71                 ar.add(tok);
72                 
73
74                 
75             }
76             this.tokens = ar;
77             
78         }
79         
80         
81         
82         Gee.ArrayList<Token>  collapse(Gee.ArrayList<Token>  ar) 
83         {
84             
85             var st = new TokenStream(ar);
86             var ret = new Gee.ArrayList<Token>();
87             
88             while (true) {
89                 var  tok = st.look(1,true);
90                 if (tok == null) {
91                   //  Seed.print(TokenStream.toString(ret));
92                     return ret;
93                 }
94                 // console.log(tok.data);
95                 
96                 debug("COL: %s", tok.asString());
97                 
98                 switch(tok.type) {
99                     case "VOID": 
100                         return ret; //EOF
101                         
102                         
103                     case "KEYW": 
104                     case "TOKN":
105                     case "NAME":
106                     case "STRN":
107                     case "NUMB":
108                     case "REGX":
109                                 var nn = st.next();
110                                 if (nn != null) { 
111                                 ret.add(nn);
112                         }
113                         continue;
114                         
115                     case "PUNC":
116                         switch (tok.data) {
117                             case "[":
118                             case "{":
119                             case "(":
120                                 
121                                 var start = st.cursor;
122                                 //st.next(); << no need to shift, balance will start at first character..
123                                 
124                                 var add = st.balance(tok.data);
125                                 
126                                 debug("BALANCE returned %d items\n", add.size);
127                                 
128                                 
129                                // if (!add) {
130                                     //console.dump(tok);
131                                     //console.dump(start + '...' + st.cursor);
132                                     //console.dump(st.tokens);
133                                  
134                                 //}
135                                 if (add.size > 0) {
136                                         add.remove_at(0);  // remove the first element... (as it's the 
137                                 }
138                                 //Seed.print("ADD");
139                                 //Seed.print(JSON.stringify(add, null,4));
140                                 
141                                 
142                                 
143                                 var toks = add.size > 0 ? this.collapse(add) : add;
144                                 
145                                 tok.items = new Gee.ArrayList<Gee.ArrayList<Token>>(); //?? needed?
146                                 tok.props = new Gee.HashMap<string,TokenKeyMap>();
147                                  
148                                 
149                                 if (tok.data != "{") {
150                                     // paramters or array elements..
151                                     tok.items = this.toItems(toks, ",");
152                                 } else {
153                                     // check for types.. it could be a list of statements.. or object
154                                     // format "{" "xXXX" ":" << looks for the ':'.. seems to work.. not sure if it's foolproof...
155                                     
156                                     var ost = new  TokenStream(toks);
157                                     //console.dump(ost.look(2,true) );
158                                     if (ost.look(2,true) != null && ost.look(2,true).data == ":") {
159                                                 // object properties...
160                                         tok.props = this.toProps(toks);
161                                     } else {
162                                         // list of statemetns..
163                                         tok.items = this.toItems(toks, ";{");;
164                                     }
165                                     
166                                     
167                                 }
168                                  
169                                 
170                                 
171                                 
172                                 
173                                 
174                                 
175                                 //Seed.print(" ADD : " + add.length  +  " ITEMS: " + tok.items.length);
176                                 
177                                 ret.add(tok);
178                                 
179                                 continue;
180                    
181                             default:
182                                 ret.add(st.next());
183                                 continue;
184                         }
185                        print("OOPS");
186                         continue;
187                     default : 
188                        print("OOPS" + tok.type);
189                         continue;
190                 }
191             }
192                 
193                 
194             
195             
196             
197             
198             
199             
200             
201             
202         }
203         // array of arrays of tokens
204         Gee.ArrayList<Gee.ArrayList<Token>>  toItems(Gee.ArrayList<Token>  ar, string sep)
205         {
206             var ret = new Gee.ArrayList<Gee.ArrayList<Token>>() ;
207             var g =  new Gee.ArrayList<Token>() ;
208               
209             for (var i = 0; i < ar.size; i ++) {
210                 if (sep.index_of(ar.get(i).data) < 0) {
211                     g.add(ar.get(i));
212                     continue;
213                 }
214                 // var a=..., b =...
215                 if ((ar.get(i).data != ";") && g.size> 0  && (g[0].name == "VAR")) {;
216                     g.add(ar.get(i));
217                     continue;
218                 }
219                 
220                 g.add(ar.get(i));
221                 ret.add(g);
222                 g =  new Gee.ArrayList<Token>() ;
223                 
224             }
225             // last..
226             if (g.size > 0) {
227                 ret.add(g);
228             }
229             return ret;
230             
231         }
232         
233         Gee.HashMap<string,TokenKeyMap> toProps (Gee.ArrayList<Token> ar)
234         {
235             
236             var ret = new Gee.HashMap<string,TokenKeyMap>();
237                
238             var g = new TokenKeyMap();
239                
240             
241             var k = "";
242             var state = 0;
243             for (var i = 0; i < ar.size; i ++) {
244                 
245                 switch(state) {
246                     case 0:
247                         k = ar.get(i).data;
248                         g.key = ar.get(i);
249                         state = 1;
250                         continue;
251                     case 1:
252                         state =2; // should be ':'
253                         continue;
254                     case 2:
255                         g.vals.add( ar.get(i));
256                         if ( ar.get(i).data != ",") {
257                             continue;
258                         }
259                         ret.set(k, g);
260                         g = new TokenKeyMap();
261                         state = 0;
262                         continue;
263                    
264                 }
265             }
266              // last.. - if g.val.length is 0 then it's a trailing ','...
267              // we should really throw a syntax error in that case..
268             if (k.length > 0 && g.vals.size > 0) {
269                 ret.set(k, g);
270             }
271             return ret;
272             
273             
274         }
275
276         }   
277     
278 }