Spaces:
Sleeping
Sleeping
| // -*- js2 -*- | |
| global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); | |
| var fs = require("fs"), | |
| jsp = require("./lib/parse-js"), | |
| pro = require("./lib/process"); | |
| pro.set_logger(function(msg){ | |
| sys.debug(msg); | |
| }); | |
| var options = { | |
| ast: false, | |
| mangle: true, | |
| mangle_toplevel: false, | |
| squeeze: true, | |
| make_seqs: true, | |
| dead_code: true, | |
| beautify: false, | |
| verbose: false, | |
| show_copyright: true, | |
| out_same_file: false, | |
| extra: false, | |
| unsafe: false, // XXX: extra & unsafe? but maybe we don't want both, so.... | |
| beautify_options: { | |
| indent_level: 4, | |
| indent_start: 0, | |
| quote_keys: false, | |
| space_colon: false | |
| }, | |
| output: true // stdout | |
| }; | |
| var args = jsp.slice(process.argv, 2); | |
| var filename; | |
| out: while (args.length > 0) { | |
| var v = args.shift(); | |
| switch (v) { | |
| case "-b": | |
| case "--beautify": | |
| options.beautify = true; | |
| break; | |
| case "-i": | |
| case "--indent": | |
| options.beautify_options.indent_level = args.shift(); | |
| break; | |
| case "-q": | |
| case "--quote-keys": | |
| options.beautify_options.quote_keys = true; | |
| break; | |
| case "-mt": | |
| case "--mangle-toplevel": | |
| options.mangle_toplevel = true; | |
| break; | |
| case "--no-mangle": | |
| case "-nm": | |
| options.mangle = false; | |
| break; | |
| case "--no-squeeze": | |
| case "-ns": | |
| options.squeeze = false; | |
| break; | |
| case "--no-seqs": | |
| options.make_seqs = false; | |
| break; | |
| case "--no-dead-code": | |
| options.dead_code = false; | |
| break; | |
| case "--no-copyright": | |
| case "-nc": | |
| options.show_copyright = false; | |
| break; | |
| case "-o": | |
| case "--output": | |
| options.output = args.shift(); | |
| break; | |
| case "--overwrite": | |
| options.out_same_file = true; | |
| break; | |
| case "-v": | |
| case "--verbose": | |
| options.verbose = true; | |
| break; | |
| case "--ast": | |
| options.ast = true; | |
| break; | |
| case "--extra": | |
| options.extra = true; | |
| break; | |
| case "--unsafe": | |
| options.unsafe = true; | |
| break; | |
| default: | |
| filename = v; | |
| break out; | |
| } | |
| } | |
| if (filename) { | |
| fs.readFile(filename, "utf8", function(err, text){ | |
| if (err) { | |
| throw err; | |
| } | |
| output(squeeze_it(text)); | |
| }); | |
| } else { | |
| var stdin = process.openStdin(); | |
| stdin.setEncoding("utf8"); | |
| var text = ""; | |
| stdin.on("data", function(chunk){ | |
| text += chunk; | |
| }); | |
| stdin.on("end", function() { | |
| output(squeeze_it(text)); | |
| }); | |
| } | |
| function output(text) { | |
| var out; | |
| if (options.out_same_file && filename) | |
| options.output = filename; | |
| if (options.output === true) { | |
| out = process.stdout; | |
| } else { | |
| out = fs.createWriteStream(options.output, { | |
| flags: "w", | |
| encoding: "utf8", | |
| mode: 0644 | |
| }); | |
| } | |
| out.write(text); | |
| out.end(); | |
| }; | |
| // --------- main ends here. | |
| function show_copyright(comments) { | |
| var ret = ""; | |
| for (var i = 0; i < comments.length; ++i) { | |
| var c = comments[i]; | |
| if (c.type == "comment1") { | |
| ret += "//" + c.value + "\n"; | |
| } else { | |
| ret += "/*" + c.value + "*/"; | |
| } | |
| } | |
| return ret; | |
| }; | |
| function squeeze_it(code) { | |
| var result = ""; | |
| if (options.show_copyright) { | |
| var initial_comments = []; | |
| // keep first comment | |
| var tok = jsp.tokenizer(code, false), c; | |
| c = tok(); | |
| var prev = null; | |
| while (/^comment/.test(c.type) && (!prev || prev == c.type)) { | |
| initial_comments.push(c); | |
| prev = c.type; | |
| c = tok(); | |
| } | |
| result += show_copyright(initial_comments); | |
| } | |
| try { | |
| var ast = time_it("parse", function(){ return jsp.parse(code); }); | |
| if (options.mangle) | |
| ast = time_it("mangle", function(){ return pro.ast_mangle(ast, options.mangle_toplevel); }); | |
| if (options.squeeze) | |
| ast = time_it("squeeze", function(){ | |
| ast = pro.ast_squeeze(ast, { | |
| make_seqs : options.make_seqs, | |
| dead_code : options.dead_code, | |
| extra : options.extra | |
| }); | |
| if (options.unsafe) | |
| ast = pro.ast_squeeze_more(ast); | |
| return ast; | |
| }); | |
| if (options.ast) | |
| return sys.inspect(ast, null, null); | |
| result += time_it("generate", function(){ return pro.gen_code(ast, options.beautify && options.beautify_options) }); | |
| return result; | |
| } catch(ex) { | |
| sys.debug(ex.stack); | |
| sys.debug(sys.inspect(ex)); | |
| sys.debug(JSON.stringify(ex)); | |
| } | |
| }; | |
| function time_it(name, cont) { | |
| if (!options.verbose) | |
| return cont(); | |
| var t1 = new Date().getTime(); | |
| try { return cont(); } | |
| finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); } | |
| }; | |