var path = require("path"); var fs = require("fs"); var vm = require("vm"); var sys = require("util"); var MOZ_SourceMap = require("source-map"); function load_global(file) { file = path.resolve(path.dirname(module.filename), file); try { var code = fs.readFileSync(file, "utf8"); return eval(code); } catch(ex) { // XXX: in case of a syntax error, the message is kinda // useless. (no location information). sys.debug("ERROR in file: " + file + " / " + ex); process.exit(1); } }; var FILES = exports.FILES = [ "../lib/utils.js", "../lib/ast.js", "../lib/parse.js", "../lib/transform.js", "../lib/scope.js", "../lib/output.js", "../lib/compress.js", "../lib/sourcemap.js", "../lib/mozilla-ast.js", "../lib/translate.js", "../lib/std.js" ].map(function(file){ return path.join(path.dirname(fs.realpathSync(__filename)), file); }); FILES.forEach(load_global); Cola.AST_Node.warn_function = function(txt) { sys.error("WARN: " + txt); }; Cola.getSource = function(file) { return fs.readFileSync(path.join(process.cwd(), file), "utf8"); }; // XXX: perhaps we shouldn't export everything but heck, I'm lazy. for (var i in Cola) { if (Cola.hasOwnProperty(i)) { exports[i] = Cola[i]; } } exports.minify = function(files, options) { options = Cola.defaults(options, { spidermonkey : false, outSourceMap : null, sourceRoot : null, inSourceMap : null, fromString : false, warnings : false, mangle : {}, output : null, compress : {}, is_js : false, main_binding : true }); Cola.base54.reset(); // 1. parse var toplevel = null, sourcesContent = {}; if (options.spidermonkey) { toplevel = Cola.AST_Node.from_mozilla_ast(files); } else { if (typeof files == "string") files = [ files ]; files.forEach(function(file){ var code = options.fromString ? file : fs.readFileSync(file, "utf8"); sourcesContent[file] = code; toplevel = Cola.parse(code, { filename: options.fromString ? "?" : file, toplevel: toplevel, is_js : options.is_js }); if (!options.is_js) toplevel = toplevel.toJavaScript({ main_binding: options.main_binding, parser: { filename: options.fromString ? "?" : file, is_js : options.is_js } }); }); } // 2. compress if (options.compress) { var compress = { warnings: options.warnings, is_js : options.is_js }; Cola.merge(compress, options.compress); toplevel.figure_out_scope(); var sq = new Cola.Compressor(compress); toplevel = toplevel.transform(sq); } // 3. mangle if (options.mangle) { toplevel.figure_out_scope(); toplevel.compute_char_frequency(); toplevel.mangle_names(options.mangle); } // 4. output var inMap = options.inSourceMap; var output = {}; if (typeof options.inSourceMap == "string") { inMap = fs.readFileSync(options.inSourceMap, "utf8"); } if (options.outSourceMap) { output.source_map = new Cola.SourceMap({ file: options.outSourceMap, orig: inMap, root: options.sourceRoot }); if (options.sourceMapIncludeSources) { for (var file in sourcesContent) { if (sourcesContent.hasOwnProperty(file)) { options.source_map.get().setSourceContent(file, sourcesContent[file]); } } } } if (options.output) { Cola.merge(output, options.output); } var stream = new Cola.OutputStream(output); toplevel.print(stream); return { code : stream + "", map : output.source_map + "" }; }; // exports.describe_ast = function() { // function doitem(ctor) { // var sub = {}; // ctor.SUBCLASSES.forEach(function(ctor){ // sub[ctor.TYPE] = doitem(ctor); // }); // var ret = {}; // if (ctor.SELF_PROPS.length > 0) ret.props = ctor.SELF_PROPS; // if (ctor.SUBCLASSES.length > 0) ret.sub = sub; // return ret; // } // return doitem(Cola.AST_Node).sub; // } exports.describe_ast = function() { var out = new Cola.OutputStream({ beautify: true }); function doitem(ctor) { out.print("AST_" + ctor.TYPE); var props = ctor.SELF_PROPS.filter(function(prop){ return !/^\$/.test(prop); }); if (props.length > 0) { out.space(); out.with_parens(function(){ props.forEach(function(prop, i){ if (i) out.space(); out.print(prop); }); }); } if (ctor.documentation) { out.space(); out.print_string(ctor.documentation); } if (ctor.SUBCLASSES.length > 0) { out.space(); out.with_block(function(){ ctor.SUBCLASSES.forEach(function(ctor, i){ out.indent(); doitem(ctor); out.newline(); }); }); } }; doitem(Cola.AST_Node); return out + ""; };