Re-arrange files, add support for classic JS Documentor, and packer
[gnome.introspection-doc-generator] / JSDOC / CompressWhite.js
1  // <script type="text/javascript">
2 /**
3  * 
4  * pack a javascript file, and return a shorter version!
5  * 
6  * a bit picky at present with ; and crlf reading...
7  * @arg ts {TokenStream} 
8    @arg packer {Packer} 
9  */
10  
11 CompressWhite =  function (ts, packer, keepWhite)
12 {
13     keepWhite = keepWhite || false;
14     ts.rewind();
15     //var str = File.read(fn);
16     var rep_var = 1;
17     
18     while (true) {
19         var tok = ts.next();
20         if (!tok) {
21             break;
22         }
23         if (tok.type == "WHIT") {
24            
25             continue;
26             //if (tok._isDoc) {
27             //    continue;
28             //}
29             // just spaces, not \n!
30             //if (tok.data.indexOf("\n") < 0) {
31             //    continue;
32            // }
33             
34             
35         }
36         if (tok.data == "}")  {
37             
38             if (ts.lookTok(1).type == 'NAME' && ts.look(1,true).name == "NEWLINE") {
39             
40                 ts.look(0).outData = ts.look(0).data+"\n";
41             }
42             // restore.. 
43             
44             continue;
45         }
46         // add semi-colon's where linebreaks are used... - not foolproof yet.!
47         if (tok.type == "NAME")  {
48             //var tokident = ts.look(-1).data + tok.data + ts.look(1).data +  ts.look(2).data;
49             // a = new function() {} 
50             if (ts.lookTok(1).data == '=' && ts.lookTok(2).name == 'NEW'  && 
51                 ts.lookTok(3).name == 'FUNCTION') {
52                 // freeze time.. 
53                 var cu = ts.cursor;
54                 
55                 ts.balance("(");
56                 
57                 
58                 ts.balance("{");
59                 // if next is not ';' -> make it so...
60                 
61                 if (ts.lookTok(1).data != ';'  && ts.lookTok(1).data != '}' && ts.lookTok(1,true).name == "NEWLINE") {
62                     ts.look(0).outData = ts.cur().data +";";
63                 }
64                 // restore.. 
65                 ts.cursor = cu;
66                 continue;
67             }
68             // a = function() { ...
69                
70             if (ts.lookTok(1).data == '=' &&  ts.lookTok(2).name == "FUNCTION") {
71                 // freeze time.. 
72                 //println("got = function() ");
73                 var cu = ts.cursor;
74                 
75                  if (!ts.balance("(") ){
76                     ts.dump(cu-40, cu);
77                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
78                     ts.dump(cu, cu+40);
79                     
80                     throw "could not find end lbrace!!!";
81                 }
82                 //print("AFTER BALANCE (");
83                 //ts.dump(cu, ts.cursor);
84                 //ts.cursor--; // cursor at the (
85                 if (!ts.balance("{") ){
86                     ts.dump(cu-40, cu);
87                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
88                     ts.dump(cu, cu+40);
89                     
90                     throw "could not find end lbrace!!!";
91                 }
92                 //print('FN: '+ts.tokens[cu].toString());
93                 //print('F1: '+ts.lookTok(1).toString());
94                 //print('F2: '+ts.look(1,true).toString());
95                 
96                 // if next is not ';' -> make it so...
97                 // although this var a=function(){},v,c; causes 
98                 if (ts.lookTok(1).data != ';' && ts.lookTok(1).data != '}' && ts.look(1,true).name == "NEWLINE") {
99                     
100                     ts.look(0).outData = ts.look(0).data+";";
101                    // print("ADDING SEMI: " + ts.look(0).toString());
102                     //ts.dump(cu, ts.cursor+2);
103                 }
104                 
105                  //ts.dump(cu, ts.cursor+2);
106                 // restore.. 
107                 ts.cursor = cu;
108                 continue;
109             }
110             // next item is a name..
111             if ((ts.lookTok(1).type == 'NAME' || ts.lookTok(1).type == 'KEYW' ) &&  ts.look(1,true).name == "NEWLINE") {
112                 // preserve linebraek
113                 ts.look(0).outData = ts.look(0).data+"\n";
114             }
115             // method call followed by name..
116             if (ts.lookTok(1).data == "(")  {
117                 var cu = ts.cursor;
118                 
119                 ts.balance("(");
120                  // although this var a=function(){},v,c; causes 
121                 
122                 if (ts.lookTok(1).type == 'NAME' && ts.look(1,true).name == "NEWLINE") {
123                 
124                     ts.look(0).outData = ts.look(0).data+"\n";
125                 }
126                 // restore.. 
127                 ts.cursor = cu;
128                 continue;
129             }
130             
131             
132             // function a () { ... };
133                 /*
134             if (ts.look(-1).isTypeN(Script.TOKfunction) &&  ts.look(1).isTypeN(Script.TOKlparen)) {
135                 // freeze time.. 
136                 //println("got = function() ");
137                 var cu = ts.cursor;
138                 
139                 ts.balance("lparen");
140                 ts.balance("lbrace");
141                 // if next is not ';' -> make it so...
142                 // although this var a=function(){},v,c; causes 
143                 if (!ts.look(1).isData(';') && !ts.look(1).isData('}') && ts.look(1,true).isLineBreak()) {
144                     ts.cur().outData = ts.cur().data+";";
145                 }
146                 // restore.. 
147                 ts.cursor = cu;
148                 continue;
149             }
150             */
151             
152             // a = { ....
153                 
154             if (ts.lookTok(1).data == '=' &&  ts.lookTok(2).data == '{') {
155                 // freeze time.. 
156                 //println("----------*** 3 *** --------------");
157                 var cu = ts.cursor;
158                 
159                 if (!ts.balance("{") ){
160                     ts.dump(cu-40, cu);
161                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
162                     ts.dump(cu, cu+40);
163                     
164                     throw "could not find end lbrace!!!";
165                 }
166                 // if next is not ';' -> make it so...
167                 
168                 if (ts.lookTok(1).data != ';' && ts.lookTok(1).data != '}' && ts.look(1,true).name=="NEWLINE") {
169                     ts.look(0).outData = ts.look(0).data +";";
170                 }
171                 // restore.. 
172                 ts.cursor = cu;
173                 continue;
174             }
175             
176             // any more??
177             // a = function(....) { } 
178           
179         }
180         
181         
182         
183          
184         //println("got Token: " + tok.type);
185         
186         
187         
188         switch(tok.data.toUpperCase()) {
189             // things that need space appending
190             case "FUNCTION":
191             case "BREAK":
192             case "CONTINUE":
193                 // if next item is a identifier..
194                 if (ts.lookTok(1).type == "NAME" || ts.lookTok(1).data.match(/^[a-z]+$/i) ) { // as include is a keyword for us!!
195                    tok.outData =  tok.data + " ";
196                 }
197                 continue;
198                 
199                 
200             case "RETURN": // if next item is not a semi; (or }
201                 if (ts.lookTok(1).data == ';' || ts.lookTok(1).data == '}') {
202                     continue;
203                 }
204                 tok.outData =  tok.data + " ";
205                 
206                 continue;
207             
208                 
209             case "ELSE": // if next item is not a semi; (or }
210                 if (!ts.lookTok(1).name == "IF") {
211                     continue;
212                 }
213                 
214                 tok.outData =  tok.data + " ";
215                 continue;
216             
217             case "++": // if previous was a plus or next is a + add a space..
218             case "--": // if previous was a - or next is a - add a space..
219             
220                 var p = (tok.data == "--" ? '-' : '+'); 
221             
222                 if (ts.lookTok(1).data == p) {
223                     tok.outData =  tok.data + " ";
224                 }
225                 if (ts.lookTok(-1).data == p) {
226                     tok.outData =  " " +  tok.data;
227                     
228                 }
229                 continue;
230             
231             case "IN": // before and after?? 
232             case "INSTANCEOF":
233                 
234                 tok.outData = " " + tok.data + " ";
235                 continue;
236             
237             case "VAR": // always after..
238             case "NEW":
239             case "DELETE":
240             case "THROW":
241             case "CASE":
242             
243             case "VOID":
244                 tok.outData =  tok.data + " ";
245                 
246                 continue
247                 
248             case "TYPEOF": // what about typeof(
249                 if (ts.lookTok(1).data != '(') {
250                     tok.outData =  tok.data + " ";
251                 }
252                 continue;
253              case ";":
254                 //remove semicolon before brace -- 
255                 //if(ts.look(1).isTypeN(Script.TOKrbrace)) {
256                 //    tok.outData = '';
257                // }
258                 continue;
259            
260             default:
261                 continue;
262         }
263     }
264     
265     ts.rewind();
266     
267     // NOW OUTPUT THE THING.
268     //var f = new File(minfile, File.NEW);
269     
270     var out = '';
271     var outoff = 0;
272     out.length = ts.slen; // prealloc.
273     out = '';
274     var tok;
275     while (true) {
276         
277         tok = keepWhite ? ts.next() : ts.nextTok();
278         
279         if (!tok) {
280             break;
281         }
282         if (tok.type == "COMM") {
283             tok.outData = '\n';
284         }
285         
286         if (tok.type == "NAME"  && tok.identifier && tok.identifier.mungedValue && tok.identifier.mungedValue.length) {
287             //f.write(tok.identifier.mungedValue);
288             out += tok.identifier.mungedValue;
289             continue;
290         }
291         
292         // at this point we can apply a text translation kit...
293         
294         if ((tok.type == 'STRN') && (tok.name== 'DOUBLE_QUOTE')) {
295             if (packer && packer.stringHandler) {
296                 out += packer.stringHandler(tok);
297                 continue;
298             }
299         }
300      
301         out += tok.outData !== false ? tok.outData : tok.data;
302         
303         if ((tok.outData == ';') && (out.length - outoff > 255)) {
304             outoff = out.length;
305             out += "\n";
306         }
307     }
308     //f.close();
309     /*
310     // remove the last ';' !!!
311     if (out.substring(out.length-1) == ';') {
312         return out.substring(0,out.length-1);
313        }
314     */
315     return out;
316     
317 }
318     
319