aboutsummaryrefslogtreecommitdiffstats
path: root/build/build/uglify.js
diff options
context:
space:
mode:
Diffstat (limited to 'build/build/uglify.js')
-rw-r--r--build/build/uglify.js285
1 files changed, 285 insertions, 0 deletions
diff --git a/build/build/uglify.js b/build/build/uglify.js
new file mode 100644
index 000000000..aad18e8ca
--- /dev/null
+++ b/build/build/uglify.js
@@ -0,0 +1,285 @@
+#! /usr/bin/env node
+// -*- js -*-
+
+global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
+var fs = require("fs");
+var jsp = require("./lib/parse-js"),
+ pro = require("./lib/process");
+
+var options = {
+ ast: false,
+ mangle: true,
+ mangle_toplevel: false,
+ squeeze: true,
+ make_seqs: true,
+ dead_code: true,
+ verbose: false,
+ show_copyright: true,
+ out_same_file: false,
+ max_line_length: 32 * 1024,
+ unsafe: false,
+ reserved_names: null,
+ defines: { },
+ codegen_options: {
+ ascii_only: false,
+ beautify: false,
+ 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.codegen_options.beautify = true;
+ break;
+ case "-i":
+ case "--indent":
+ options.codegen_options.indent_level = args.shift();
+ break;
+ case "-q":
+ case "--quote-keys":
+ options.codegen_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 "--unsafe":
+ options.unsafe = true;
+ break;
+ case "--max-line-len":
+ options.max_line_length = parseInt(args.shift(), 10);
+ break;
+ case "--reserved-names":
+ options.reserved_names = args.shift().split(",");
+ break;
+ case "-d":
+ case "--define":
+ var defarg = args.shift();
+ try {
+ var defsym = function(sym) {
+ // KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
+ // for them too ?? We don't check reserved words and the like as the
+ // define values are only substituted AFTER parsing
+ if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) {
+ throw "Don't define values for inbuilt constant '"+sym+"'";
+ }
+ return sym;
+ },
+ defval = function(v) {
+ if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) {
+ return [ "string", RegExp.$1 ];
+ }
+ else if (!isNaN(parseFloat(v))) {
+ return [ "num", parseFloat(v) ];
+ }
+ else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) {
+ return [ "name", v ];
+ }
+ else if (!v.match(/"/)) {
+ return [ "string", v ];
+ }
+ else if (!v.match(/'/)) {
+ return [ "string", v ];
+ }
+ throw "Can't understand the specified value: "+v;
+ };
+ if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) {
+ var sym = defsym(RegExp.$1),
+ val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ];
+ options.defines[sym] = val;
+ }
+ else {
+ throw "The --define option expects SYMBOL[=value]";
+ }
+ } catch(ex) {
+ sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n");
+ process.exit(1);
+ }
+ break;
+ case "--define-from-module":
+ var defmodarg = args.shift(),
+ defmodule = require(defmodarg),
+ sym,
+ val;
+ for (sym in defmodule) {
+ if (defmodule.hasOwnProperty(sym)) {
+ options.defines[sym] = function(val) {
+ if (typeof val == "string")
+ return [ "string", val ];
+ if (typeof val == "number")
+ return [ "num", val ];
+ if (val === true)
+ return [ 'name', 'true' ];
+ if (val === false)
+ return [ 'name', 'false' ];
+ if (val === null)
+ return [ 'name', 'null' ];
+ if (val === undefined)
+ return [ 'name', 'undefined' ];
+ sys.print("ERROR: In option --define-from-module "+defmodarg+"\n");
+ sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n");
+ process.exit(1);
+ return null;
+ }(defmodule[sym]);
+ }
+ }
+ break;
+ case "--ascii":
+ options.codegen_options.ascii_only = true;
+ break;
+ default:
+ filename = v;
+ break out;
+ }
+}
+
+if (options.verbose) {
+ pro.set_logger(function(msg){
+ sys.debug(msg);
+ });
+}
+
+jsp.set_logger(function(msg){
+ sys.debug(msg);
+});
+
+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);
+ if (options.output !== true) {
+ 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 tok = jsp.tokenizer(code), c;
+ c = tok();
+ result += show_copyright(c.comments_before);
+ }
+ try {
+ var ast = time_it("parse", function(){ return jsp.parse(code); });
+ if (options.mangle) ast = time_it("mangle", function(){
+ return pro.ast_mangle(ast, {
+ toplevel: options.mangle_toplevel,
+ defines: options.defines,
+ except: options.reserved_names
+ });
+ });
+ if (options.squeeze) ast = time_it("squeeze", function(){
+ ast = pro.ast_squeeze(ast, {
+ make_seqs : options.make_seqs,
+ dead_code : options.dead_code,
+ keep_comps : !options.unsafe
+ });
+ 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.codegen_options) });
+ if (!options.codegen_options.beautify && options.max_line_length) {
+ result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) });
+ }
+ 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."); }
+};