add source mappings for more node types; started CLI utility
authorMihai Bazon <mihai@bazon.net>
Sun, 2 Sep 2012 11:32:00 +0000 (14:32 +0300)
committerMihai Bazon <mihai@bazon.net>
Sun, 2 Sep 2012 11:32:00 +0000 (14:32 +0300)
bin/uglifyjs2 [new file with mode: 0755]
lib/output.js
tmp/test-maps.js
tmp/test-node.js

diff --git a/bin/uglifyjs2 b/bin/uglifyjs2
new file mode 100755 (executable)
index 0000000..d7f2657
--- /dev/null
@@ -0,0 +1,141 @@
+#! /usr/bin/env node
+// -*- js -*-
+
+var UglifyJS = require("../tools/node");
+var sys = require("util");
+var optimist = require("optimist");
+var fs = require("fs");
+var ARGS = optimist
+    .usage("uglifyjs2 [options] input1.js input2.js ...")
+    .describe("source-map", "Specify an output file where to generate source map")
+    .describe("source-map-root", "The root of the original source to be included in the source map")
+    .describe("p", "Skip prefix for original filenames that appear in source maps")
+    .alias("p", "prefix")
+    .describe("o", "Output file (default STDOUT)")
+    .alias("o", "output")
+    .describe("stats", "Display operations run time on STDERR")
+    .describe("v", "Verbose")
+    .argv
+;
+
+for (var i in ARGS) if (ARGS.hasOwnProperty(i) && /-/.test(i)) {
+    ARGS[i.replace(/-/g, "_")] = ARGS[i];
+}
+
+if (ARGS.h || ARGS.help) {
+    sys.puts(optimist.help());
+    process.exit(0);
+}
+
+var files = ARGS._.slice();
+
+if (files.length == 0) {
+    sys.error("ERROR: No input files.");
+    sys.puts(optimist.help());
+    process.exit(1);
+}
+
+if (files.indexOf("-") >= 0 && ARGS.source_map) {
+    sys.error("ERROR: Source map doesn't work with input from STDIN");
+    process.exit(1);
+}
+
+if (files.filter(function(el){ return el == "-" }).length > 1) {
+    sys.error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
+    process.exit(1);
+}
+
+var STATS = {};
+var OUTPUT_FILE = ARGS.o;
+
+var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
+    file: output,
+    root: ARGS.source_map_root
+}) : null;
+
+var output = UglifyJS.OutputStream({
+    beautify: false,
+    source_map: SOURCE_MAP
+});
+
+files.forEach(do_file);
+
+if (SOURCE_MAP) {
+    fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
+}
+
+if (OUTPUT_FILE) {
+    fs.writeFileSync(OUTPUT_FILE, output, "utf8");
+} else {
+    sys.print(output);
+    sys.error("\n");
+}
+
+if (ARGS.stats) {
+    sys.error(UglifyJS.string_template("Timing information (compressed {count} files):", {
+        count: files.length
+    }));
+    for (var i in STATS) if (STATS.hasOwnProperty(i)) {
+        sys.error(UglifyJS.string_template("- {name}: {time}s", {
+            name: i,
+            time: (STATS[i] / 1000).toFixed(3)
+        }));
+    }
+}
+
+/* -----[ functions ]----- */
+
+function do_file(file) {
+    if (ARGS.v) {
+        sys.error("Compressing " + file);
+    }
+    var code = read_whole_file(file);
+    var ast;
+    time_it("parse", function(){
+        ast = UglifyJS.parse(code);
+    });
+    time_it("scope", function(){
+        ast.figure_out_scope();
+    });
+    time_it("mangle", function(){
+        ast.mangle_names();
+    });
+    time_it("squeeze", function(){
+        var compressor = UglifyJS.Compressor();
+        ast = ast.squeeze(compressor);
+    });
+    time_it("generate", function(){
+        if (SOURCE_MAP) {
+            if (ARGS.p != null) {
+                file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/");
+            }
+            SOURCE_MAP.set_source(file);
+        }
+        ast.print(output);
+    });
+}
+
+function read_whole_file(filename) {
+    if (filename == "-") {
+        // XXX: this sucks.  How does one read the whole STDIN
+        // synchronously?
+        filename = "/dev/stdin";
+    }
+    try {
+        return fs.readFileSync(filename, "utf8");
+    } catch(ex) {
+        sys.error("ERROR: can't read file: " + filename);
+        process.exit(1);
+    }
+}
+
+function time_it(name, cont) {
+    var t1 = new Date().getTime();
+    var ret = cont();
+    if (ARGS.stats) {
+        var spent = new Date().getTime() - t1;
+        if (STATS[name]) STATS[name] += spent;
+        else STATS[name] = spent;
+    }
+    return ret;
+};
index b43d817..05bd913 100644 (file)
@@ -1009,7 +1009,17 @@ function OutputStream(options) {
     DEFMAP(AST_Debugger, basic_sourcemap_gen);
     DEFMAP(AST_Symbol, basic_sourcemap_gen);
     DEFMAP(AST_Jump, basic_sourcemap_gen);
+    DEFMAP(AST_StatementWithBody, basic_sourcemap_gen);
+    DEFMAP(AST_Lambda, basic_sourcemap_gen);
     DEFMAP(AST_PropAccess, basic_sourcemap_gen);
+    DEFMAP(AST_Switch, basic_sourcemap_gen);
+    DEFMAP(AST_BlockStatement, basic_sourcemap_gen);
+    DEFMAP(AST_Toplevel, noop);
+    DEFMAP(AST_Try, basic_sourcemap_gen);
+    DEFMAP(AST_Catch, basic_sourcemap_gen);
+    DEFMAP(AST_Finally, basic_sourcemap_gen);
+    DEFMAP(AST_Definitions, basic_sourcemap_gen);
+    DEFMAP(AST_Constant, basic_sourcemap_gen);
     DEFMAP(AST_ObjectProperty, function(self, output){
         output.add_mapping(self.start, self.key);
     });
index c89d105..438d198 100755 (executable)
@@ -28,8 +28,10 @@ function do_file(file) {
 
     // generate source into the output stream
     // first reset the current file name in the source map.
-    map.set_source(file);
-    ast.print(output);
+    UglifyJS.time_it("generate", function(){
+        map.set_source(file);
+        ast.print(output);
+    });
 };
 
 files.forEach(do_file);
index d737afd..ce03b59 100755 (executable)
@@ -22,7 +22,7 @@ time_it("scope", function(){
     ast.figure_out_scope();
 });
 
-ast.scope_warnings();
+// ast.scope_warnings();
 
 time_it("mangle", function(){
     ast.mangle_names();