Fix #5682 - fix path in title of source file
[roojspacker] / src / jsdoc / CompressWhite.vala
1  
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 namespace JSDOC 
11 {
12         public errordomain CompressWhiteError {
13             BRACE
14     }
15          
16         public string CompressWhite (TokenStream ts, Packer packer, bool keepWhite) // throws CompressWhiteError,TokenStreamError
17         {
18                 //keepWhite = keepWhite || false;
19                 ts.rewind();
20                 //ts.dumpAllFlat(); GLib.Process.exit(1);
21                 
22                 //var str = File.read(fn);
23                 var rep_var = 1;
24         
25         
26         
27                 while (true) {
28                         var tok = ts.next();
29                         if (tok == null) {
30                             break;
31                         }
32                         if (tok.type == TokenType.WHIT) {
33                            
34                             continue;
35                             //if (tok._isDoc) {
36                             //    continue;
37                             //}
38                             // just spaces, not \n!
39                             //if (tok.data.indexOf("\n") < 0) {
40                             //    continue;
41                            // }
42                             
43                             
44                         }
45                         if (tok.data == "}")  {
46                             
47                             if (ts.lookTok(0).type == TokenType.NAME && ts.look(1,true).name == TokenName.NEWLINE) {
48                                 ts.look(0,true).outData = ts.look(0,true).data+"\n";
49                             }
50                             // restore.. 
51                             
52                             continue;
53                         }
54                         // add semi-colon's where linebreaks are used... - not foolproof yet.!
55                         if (tok.type == TokenType.NAME)  {
56                             //var tokident = ts.look(-1).data + tok.data + ts.look(1).data +  ts.look(2).data;
57                             // a = new function() {} 
58                             if (ts.lookTok(1).data == "=" && ts.lookTok(2).name == TokenName.NEW  && 
59                                 ts.lookTok(3).name == TokenName.FUNCTION) {
60                                 // freeze time.. 
61                                 var cu = ts.cursor;
62                                 
63                                 ts.balance(TokenName.LEFT_PAREN); //"(");
64                                 
65                                 
66                                 ts.balance(TokenName.LEFT_CURLY); //"{");
67                                 // if next is not ';' -> make it so...
68                                 
69                                 if (ts.lookTok(1).data != ";"  && ts.lookTok(1).data != "}" && ts.lookTok(1).name == TokenName.NEWLINE) {
70                                     ts.look(0,true).outData = ts.lookTok(0).data +";";
71                                 }
72                                 // restore.. 
73                                 ts.cursor = cu;
74                                 continue;
75                             }
76                             // a = function() { ... -- add a semi colon a tthe end if not one there..
77                                
78                             if (ts.lookTok(1).data == "=" &&  ts.lookTok(2).name == TokenName.FUNCTION) {
79                                 // freeze time.. 
80                                 //println("got = function() ");
81                                 tok = ts.nextTok();
82                                 tok = ts.nextTok();
83                                 
84                                 //tok = ts.next();
85                                  var cu = ts.cursor;
86                                         //print("NEXT = should be brac: %s\n", ts.lookTok(1).asString());
87                                           
88                                //print("cursor = %d", ts.cursor);
89                                   
90                                 if (ts.lookTok(1).data != "(" || ts.balance(TokenName.LEFT_PAREN /*"("*/).size < 1 ){
91                                         print("balance ( issue on line %d\n", ts.toArray().get(cu).line);
92                                     ts.dump(cu-40, cu+2);
93                                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
94                                     ts.dump(cu+2, cu+40);
95                                     
96                                     throw new CompressWhiteError.BRACE( "could not find end lbrace!!!" );
97                                 }
98                                 //print("cursor = %d", ts.cursor);
99                                 //print("CUR = should be ): %s\n", ts.lookTok(0).asString());
100
101                                 tok = ts.nextTok();
102                                 //print("CUR = should be {: %s\n", ts.lookTok(0).asString());                           
103                                 cu = ts.cursor; // set the cursor to here.. so the next bit of the code will check inside the method.
104                                 
105                                 //print("cursor = %d", ts.cursor);
106                                // print("AFTER BALANCE (");
107                                 //ts.dump(cu, ts.cursor);
108                                 
109                                 
110                                 ts.cursor--; // cursor at the (
111                                 if (tok.data != "{" || ts.balance(TokenName.LEFT_CURLY /*"("*/).size < 1 ){
112
113                                     ts.dump(cu-40, cu);
114                                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
115                                     ts.dump(cu, cu+40);
116                                     
117                                     throw new CompressWhiteError.BRACE( "could not find end lbrace!!!");
118                                 }
119                                 //print('FN: '+ts.tokens[cu].toString());
120                                 //print('F1: '+ts.lookTok(1).toString());
121                                 //print('F2: '+ts.look(1,true).toString());
122                                 
123                                 // if next is not ';' -> make it so...
124                                 // although this var a=function(){},v,c; causes 
125                                 if (ts.lookTok(1).data != ";" && ts.lookTok(1).data != "}" && ts.look(1,true).name == TokenName.NEWLINE) {
126                                     
127                                     ts.look(0,true).outData = ts.look(0,true).data+";";
128                                    // print("ADDING SEMI: " + ts.look(0).toString());
129                                     //ts.dump(cu, ts.cursor+2);
130                                 }
131                                 
132                                  //ts.dump(cu, ts.cursor+2);
133                                 // restore.. 
134                                 ts.cursor = cu;
135                                 continue;
136                             }
137                             // next item is a name..
138                             if ((ts.lookTok(1).type == TokenType.NAME || ts.lookTok(1).type == TokenType.KEYW ) 
139                                                 &&  ts.look(1,true).name == TokenName.NEWLINE) {
140                                 // preserve linebraek
141                                 ts.look(0,true).outData = ts.look(0,true).data+"\n";
142                             }
143                             // method call followed by name..
144                             if (ts.lookTok(1).data == "(")  {
145                                 var cu = ts.cursor;
146                                 
147                                  ts.balance(TokenName.LEFT_PAREN); //"(");
148                                  // although this var a=function(){},v,c; causes 
149                                 
150                                 if (ts.lookTok(1).type == TokenType.NAME && ts.look(1,true).name == TokenName.NEWLINE) {
151                                 
152                                     ts.look(0,true).outData = ts.look(0,true).data+"\n";
153                                 }
154                                 // restore.. 
155                                 ts.cursor = cu;
156                                 continue;
157                             }
158                             
159                             
160                             // function a () { ... };
161                                 /*
162                             if (ts.look(-1).isTypeN(Script.TOKfunction) &&  ts.look(1).isTypeN(Script.TOKlparen)) {
163                                 // freeze time.. 
164                                 //println("got = function() ");
165                                 var cu = ts.cursor;
166                                 
167                                 ts.balance("lparen");
168                                 ts.balance("lbrace");
169                                 // if next is not ';' -> make it so...
170                                 // although this var a=function(){},v,c; causes 
171                                 if (!ts.look(1).isData(';') && !ts.look(1).isData('}') && ts.look(1,true).isLineBreak()) {
172                                     ts.cur().outData = ts.cur().data+";";
173                                 }
174                                 // restore.. 
175                                 ts.cursor = cu;
176                                 continue;
177                             }
178                             */
179                             
180                             // a = { ....
181                                 
182                             if (ts.lookTok(1).data == "=" &&  ts.lookTok(2).data == "{") {
183                                 // freeze time.. 
184                                 //println("----------*** 3 *** --------------");
185                                 var cu = ts.cursor;
186                                 ;
187                                 if (ts.balance(TokenName.LEFT_CURLY /*"{" */).size < 1 ){
188
189                                     ts.dump(cu-40, cu);
190                                     print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
191                                     ts.dump(cu, cu+40);
192                                     
193                                     throw new CompressWhiteError.BRACE("could not find end lbrace!!!");
194                                 }
195                                 // if next is not ';' -> make it so...
196                                 
197                                 if (ts.lookTok(1).data != ";" && ts.lookTok(1).data != "}" && ts.look(1,true).name==TokenName.NEWLINE) {
198                                     ts.look(0,true).outData = ts.look(0,true).data +";";
199                                 }
200                                 // restore.. 
201                                 ts.cursor = cu;
202                                 continue;
203                             }
204                             
205                             // any more??
206                             // a = function(....) { } 
207                           
208                         }
209                         
210                         
211                         
212                          
213                         //println("got Token: " + tok.type);
214                         
215                         
216                         
217                         switch(tok.name) {
218                             // things that need space appending
219                             case TokenName.FUNCTION:
220                             case TokenName.BREAK:
221                             case TokenName.CONTINUE:
222                                 // if next item is a identifier..
223                                 if (ts.lookTok(1).type == TokenType.NAME || Regex.match_simple("^[a-z]+$", ts.lookTok(1).data, GLib.RegexCompileFlags.CASELESS) ) { // as include is a keyword for us!!
224                                    tok.outData =  tok.data + " ";
225                                 }
226                                 continue;
227                                 
228                                 
229                             case TokenName.RETURN: // if next item is not a semi; (or }
230                                 if (ts.lookTok(1).data == ";" || ts.lookTok(1).data == "}") {
231                                     continue;
232                                 }
233                                 tok.outData =  tok.data + " ";
234                                 
235                                 continue;
236                             
237                                 
238                             case TokenName.ELSE: // if next item is not a semi; (or }
239                                 if (ts.lookTok(1).name != TokenName.IF) {
240                                     continue;
241                                 }
242                                 // add a space if next element is 'IF'
243                                 tok.outData =  tok.data + " ";
244                                 continue;
245                             
246                             case TokenName.INCREMENT: //"++": // if previous was a plus or next is a + add a space..
247                             case TokenName.DECREMENT: //"--": // if previous was a - or next is a - add a space..
248                             
249                                 var p = (tok.data == "--" ? "-" : "+"); 
250                             
251                                 if (ts.lookTok(1).data == p) {
252                                     tok.outData =  tok.data + " ";
253                                 }
254                                 if (ts.lookTok(-1).data == p) {
255                                     tok.outData =  " " +  tok.data;
256                                     
257                                 }
258                                 continue;
259                             
260                             case TokenName.IN: // before and after?? 
261                             case TokenName.INSTANCEOF:
262                                 
263                                 tok.outData = " " + tok.data + " ";
264                                 continue;
265                             
266                             case TokenName.VAR: // always after..
267                             case TokenName.NEW:
268                             case TokenName.DELETE:
269                             case TokenName.THROW:
270                             case TokenName.CASE:
271                             case TokenName.CONST:
272                             case TokenName.VOID:
273                                 tok.outData =  tok.data + " ";
274                                 
275                                 continue;
276                                 
277                             case TokenName.TYPEOF: // what about typeof(
278                                 if (ts.lookTok(1).data != "(") {
279                                     tok.outData =  tok.data + " ";
280                                 }
281                                 continue;
282                              case TokenName.SEMICOLON: //";":
283                                 //remove semicolon before brace -- 
284                                 //if(ts.look(1).isTypeN(Script.TOKrbrace)) {
285                                 //    tok.outData = '';
286                                // }
287                                 continue;
288                            
289                             default:
290                                 continue;
291                         }
292                 }
293         
294                 ts.rewind();
295         
296                 // NOW OUTPUT THE THING.
297                 //var f = new File(minfile, File.NEW);
298         
299                 var outstr = "";
300                 var outoff = 0;
301                 //try { out.length = ts.slen; } catch (e) {} // prealloc.
302         
303
304                 Token tok;
305                 while (true) {
306                         
307                         tok = keepWhite ? ts.next() : ts.nextTok();
308                         
309                         if (tok == null) {
310                             break;
311                         }
312                         if (tok.type == TokenType.COMM) {
313                             tok.outData = "\n";
314                         }
315                         
316                         ///print(tok.type + ':' + tok.data);
317                         
318                         if (tok.type == TokenType.NAME  &&
319                                  tok.identifier != null  &&
320                             tok.identifier.mungedValue.length > 0) {
321                             //f.write(tok.identifier.mungedValue);
322                             //print("MUNGED: " + tok.identifier.mungedValue);
323                             outstr += tok.identifier.mungedValue;
324                             continue;
325                         }
326                         
327                         // at this point we can apply a text translation kit...
328                         // NOT SUPPORTED..
329                         //if ((tok.type == "STRN") && (tok.name== "DOUBLE_QUOTE")) {
330                         //    if (packer && packer.stringHandler) {
331                         //        outstr += packer.stringHandler(tok);
332                         //        continue;
333                         //    }
334                         //}
335                  
336                         outstr += tok.outData != "" ? tok.outData : tok.data;
337                         
338                         if ((tok.name == TokenName.SEMICOLON || tok.name == TokenName.RIGHT_CURLY) && (outstr.length - outoff > 255)) {
339                             outoff = outstr.length;
340                             outstr += "\n";
341                         }
342                 }
343                 //f.close();
344                 /*
345                 // remove the last ';' !!!
346                 if (out.substring(out.length-1) == ';') {
347                         return out.substring(0,out.length-1);
348                    }
349                 */
350                 return outstr;
351         
352         }
353          
354 }