/** * * pack a javascript file, and return a shorter version! * * a bit picky at present with ; and crlf reading... * @arg ts {TokenStream} @arg packer {Packer} */ namespace JSDOC { public errordomain CompressWhiteError { BRACE } public string CompressWhite (TokenStream ts, Packer packer, bool keepWhite) // throws CompressWhiteError,TokenStreamError { //keepWhite = keepWhite || false; ts.rewind(); //ts.dumpAllFlat(); GLib.Process.exit(1); //var str = File.read(fn); var rep_var = 1; while (true) { var tok = ts.next(); if (tok == null) { break; } if (tok.type == "WHIT") { continue; //if (tok._isDoc) { // continue; //} // just spaces, not \n! //if (tok.data.indexOf("\n") < 0) { // continue; // } } if (tok.data == "}") { if (ts.lookTok(0).type == "NAME" && ts.look(1,true).name == "NEWLINE") { ts.look(0,true).outData = ts.look(0,true).data+"\n"; } // restore.. continue; } // add semi-colon's where linebreaks are used... - not foolproof yet.! if (tok.type == "NAME") { //var tokident = ts.look(-1).data + tok.data + ts.look(1).data + ts.look(2).data; // a = new function() {} if (ts.lookTok(1).data == "=" && ts.lookTok(2).name == "NEW" && ts.lookTok(3).name == "FUNCTION") { // freeze time.. var cu = ts.cursor; ts.balance("("); ts.balance("{"); // if next is not ';' -> make it so... if (ts.lookTok(1).data != ";" && ts.lookTok(1).data != "}" && ts.lookTok(1).name == "NEWLINE") { ts.look(0,true).outData = ts.lookTok(0).data +";"; } // restore.. ts.cursor = cu; continue; } // a = function() { ... -- add a semi colon a tthe end if not one there.. if (ts.lookTok(1).data == "=" && ts.lookTok(2).name == "FUNCTION") { // freeze time.. //println("got = function() "); tok = ts.nextTok(); tok = ts.nextTok(); //tok = ts.next(); var cu = ts.cursor; //print("NEXT = should be brac: %s\n", ts.lookTok(1).asString()); //print("cursor = %d", ts.cursor); if (ts.lookTok(1).data != "(" || ts.balance("(").size < 1 ){ print("balance ( issue on line %d\n", ts.toArray().get(cu).line); ts.dump(cu-40, cu+2); print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>"); ts.dump(cu+2, cu+40); throw new CompressWhiteError.BRACE( "could not find end lbrace!!!" ); } //print("cursor = %d", ts.cursor); //print("CUR = should be ): %s\n", ts.lookTok(0).asString()); tok = ts.nextTok(); //print("CUR = should be {: %s\n", ts.lookTok(0).asString()); cu = ts.cursor; // set the cursor to here.. so the next bit of the code will check inside the method. //print("cursor = %d", ts.cursor); //print("AFTER BALANCE ("); //ts.dump(cu, ts.cursor); //ts.cursor--; // cursor at the ( if (tok.data != "{" || ts.balance("{").size < 1 ){ ts.dump(cu-40, cu); print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>"); ts.dump(cu, cu+40); throw new CompressWhiteError.BRACE( "could not find end lbrace!!!"); } //print('FN: '+ts.tokens[cu].toString()); //print('F1: '+ts.lookTok(1).toString()); //print('F2: '+ts.look(1,true).toString()); // if next is not ';' -> make it so... // although this var a=function(){},v,c; causes if (ts.lookTok(1).data != ";" && ts.lookTok(1).data != "}" && ts.look(1,true).name == "NEWLINE") { ts.look(0,true).outData = ts.look(0,true).data+";"; // print("ADDING SEMI: " + ts.look(0).toString()); //ts.dump(cu, ts.cursor+2); } //ts.dump(cu, ts.cursor+2); // restore.. ts.cursor = cu; continue; } // next item is a name.. if ((ts.lookTok(1).type == "NAME" || ts.lookTok(1).type == "KEYW" ) && ts.look(1,true).name == "NEWLINE") { // preserve linebraek ts.look(0,true).outData = ts.look(0,true).data+"\n"; } // method call followed by name.. if (ts.lookTok(1).data == "(") { var cu = ts.cursor; ts.balance("("); // although this var a=function(){},v,c; causes if (ts.lookTok(1).type == "NAME" && ts.look(1,true).name == "NEWLINE") { ts.look(0,true).outData = ts.look(0,true).data+"\n"; } // restore.. ts.cursor = cu; continue; } // function a () { ... }; /* if (ts.look(-1).isTypeN(Script.TOKfunction) && ts.look(1).isTypeN(Script.TOKlparen)) { // freeze time.. //println("got = function() "); var cu = ts.cursor; ts.balance("lparen"); ts.balance("lbrace"); // if next is not ';' -> make it so... // although this var a=function(){},v,c; causes if (!ts.look(1).isData(';') && !ts.look(1).isData('}') && ts.look(1,true).isLineBreak()) { ts.cur().outData = ts.cur().data+";"; } // restore.. ts.cursor = cu; continue; } */ // a = { .... if (ts.lookTok(1).data == "=" && ts.lookTok(2).data == "{") { // freeze time.. //println("----------*** 3 *** --------------"); var cu = ts.cursor; if (ts.balance("{").size < 1 ){ ts.dump(cu-40, cu); print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>"); ts.dump(cu, cu+40); throw new CompressWhiteError.BRACE("could not find end lbrace!!!"); } // if next is not ';' -> make it so... if (ts.lookTok(1).data != ";" && ts.lookTok(1).data != "}" && ts.look(1,true).name=="NEWLINE") { ts.look(0,true).outData = ts.look(0,true).data +";"; } // restore.. ts.cursor = cu; continue; } // any more?? // a = function(....) { } } //println("got Token: " + tok.type); switch(tok.data.up()) { // things that need space appending case "FUNCTION": case "BREAK": case "CONTINUE": // if next item is a identifier.. if (ts.lookTok(1).type == "NAME" || Regex.match_simple("^[a-z]+$", ts.lookTok(1).data, GLib.RegexCompileFlags.CASELESS) ) { // as include is a keyword for us!! tok.outData = tok.data + " "; } continue; case "RETURN": // if next item is not a semi; (or } if (ts.lookTok(1).data == ";" || ts.lookTok(1).data == "}") { continue; } tok.outData = tok.data + " "; continue; case "ELSE": // if next item is not a semi; (or } if (ts.lookTok(1).name != "IF") { continue; } // add a space if next element is 'IF' tok.outData = tok.data + " "; continue; case "++": // if previous was a plus or next is a + add a space.. case "--": // if previous was a - or next is a - add a space.. var p = (tok.data == "--" ? "-" : "+"); if (ts.lookTok(1).data == p) { tok.outData = tok.data + " "; } if (ts.lookTok(-1).data == p) { tok.outData = " " + tok.data; } continue; case "IN": // before and after?? case "INSTANCEOF": tok.outData = " " + tok.data + " "; continue; case "VAR": // always after.. case "NEW": case "DELETE": case "THROW": case "CASE": case "CONST": case "VOID": tok.outData = tok.data + " "; continue; case "TYPEOF": // what about typeof( if (ts.lookTok(1).data != "(") { tok.outData = tok.data + " "; } continue; case ";": //remove semicolon before brace -- //if(ts.look(1).isTypeN(Script.TOKrbrace)) { // tok.outData = ''; // } continue; default: continue; } } ts.rewind(); // NOW OUTPUT THE THING. //var f = new File(minfile, File.NEW); var outstr = ""; var outoff = 0; //try { out.length = ts.slen; } catch (e) {} // prealloc. Token tok; while (true) { tok = keepWhite ? ts.next() : ts.nextTok(); if (tok == null) { break; } if (tok.type == "COMM") { tok.outData = "\n"; } ///print(tok.type + ':' + tok.data); if (tok.type == "NAME" && tok.identifier != null && tok.identifier.mungedValue.length > 0) { //f.write(tok.identifier.mungedValue); //print("MUNGED: " + tok.identifier.mungedValue); outstr += tok.identifier.mungedValue; continue; } // at this point we can apply a text translation kit... // NOT SUPPORTED.. //if ((tok.type == "STRN") && (tok.name== "DOUBLE_QUOTE")) { // if (packer && packer.stringHandler) { // outstr += packer.stringHandler(tok); // continue; // } //} outstr += tok.outData != "" ? tok.outData : tok.data; if ((tok.outData == ";") && (outstr.length - outoff > 255)) { outoff = outstr.length; outstr += "\n"; } } //f.close(); /* // remove the last ';' !!! if (out.substring(out.length-1) == ';') { return out.substring(0,out.length-1); } */ return outstr; } }