support defines
authorMihai Bazon <mihai@bazon.net>
Tue, 2 Oct 2012 10:20:07 +0000 (13:20 +0300)
committerMihai Bazon <mihai@bazon.net>
Tue, 2 Oct 2012 10:20:07 +0000 (13:20 +0300)
bin/uglifyjs2
lib/compress.js
lib/scope.js

index ea82ddf..63eba7c 100755 (executable)
@@ -22,6 +22,7 @@ For example -p 3 will drop 3 directories from file names and ensure they are rel
     .describe("c", "Enable compressor/pass compressor options. \
 Pass options like -c hoist_vars=false,if_return=false. \
 Use -c with no argument if you want to disable the squeezer entirely.")
+    .describe("d", "Global definitions")
 
     .describe("stats", "Display operations run time on STDERR.")
     .describe("v", "Verbose")
@@ -32,10 +33,12 @@ Use -c with no argument if you want to disable the squeezer entirely.")
     .alias("b", "beautify")
     .alias("m", "mangle")
     .alias("c", "compress")
+    .alias("d", "define")
 
     .string("b")
     .string("m")
     .string("c")
+    .string("d")
     .boolean("v")
     .boolean("stats")
 
@@ -67,7 +70,7 @@ function getOptions(x) {
             var a = opt.split(/\s*[=:]\s*/);
             ret[a[0]] = a.length > 1 ? new Function("return(" + a[1] + ")")() : true;
         });
-        normalize(ret)
+        normalize(ret);
     }
     return ret;
 }
@@ -76,6 +79,10 @@ var COMPRESS = getOptions("c");
 var MANGLE = getOptions("m");
 var BEAUTIFY = getOptions("b");
 
+if (COMPRESS && ARGS.d) {
+    COMPRESS.global_defs = getOptions("d");
+}
+
 var OUTPUT_OPTIONS = {
     beautify: BEAUTIFY ? true : false
 };
index ecd9c95..d790a28 100644 (file)
@@ -65,7 +65,8 @@ function Compressor(options, false_by_default) {
         join_vars     : !false_by_default,
         cascade       : !false_by_default,
 
-        warnings      : true
+        warnings      : true,
+        global_defs   : {}
     }, true);
 };
 
@@ -132,6 +133,30 @@ merge(Compressor.prototype, {
         return new ctor(props);
     };
 
+    function make_node_from_constant(compressor, val, orig) {
+        switch (typeof val) {
+          case "string":
+            return make_node(AST_String, orig, {
+                value: val
+            }).optimize(compressor);
+          case "number":
+            return make_node(isNaN(val) ? AST_NaN : AST_Number, orig, {
+                value: val
+            }).optimize(compressor);
+          case "boolean":
+            return make_node(val ? AST_True : AST_False, orig);
+          case "undefined":
+            return make_node(AST_Undefined, orig).optimize(compressor);
+          default:
+            if (val === null) {
+                return make_node(AST_Null, orig).optimize(compressor);
+            }
+            throw new Error(string_template("Can't handle constant of type: {type}", {
+                type: typeof val
+            }));
+        }
+    };
+
     function as_statement_array(thing) {
         if (thing === null) return [];
         if (thing instanceof AST_BlockStatement) return thing.body;
@@ -493,33 +518,7 @@ merge(Compressor.prototype, {
         AST_Node.DEFMETHOD("evaluate", function(compressor){
             if (!compressor.option("evaluate")) return [ this ];
             try {
-                var val = this._eval(), ast;
-                switch (typeof val) {
-                  case "string":
-                    ast = make_node(AST_String, this, {
-                        value: val
-                    }).optimize(compressor);
-                    break;
-                  case "number":
-                    ast = make_node(isNaN(val) ? AST_NaN : AST_Number, this, {
-                        value: val
-                    }).optimize(compressor);
-                    break;
-                  case "boolean":
-                    ast = make_node(val ? AST_True : AST_False, this);
-                    break;
-                  case "undefined":
-                    ast = make_node(AST_Undefined, this).optimize(compressor);
-                    break;
-                  default:
-                    if (val === null) {
-                        ast = make_node(AST_Null, this).optimize(compressor);
-                        break;
-                    }
-                    throw new Error(string_template("Can't handle constant of type: {type}", {
-                        type: typeof val
-                    }));
-                }
+                var val = this._eval(), ast = make_node_from_constant(compressor, val, this);
                 return [ best_of(ast, this), val ];
             } catch(ex) {
                 if (ex !== def) throw ex;
@@ -1439,11 +1438,17 @@ merge(Compressor.prototype, {
     });
 
     OPT(AST_SymbolRef, function(self, compressor){
-        if (self.undeclared()) switch (self.name) {
-          case "undefined":
-            return make_node(AST_Undefined, self);
-          case "NaN":
-            return make_node(AST_NaN, self);
+        if (self.undeclared()) {
+            var defines = compressor.option("global_defs");
+            if (defines && HOP(defines, self.name)) {
+                return make_node_from_constant(compressor, defines[self.name], self);
+            }
+            switch (self.name) {
+              case "undefined":
+                return make_node(AST_Undefined, self);
+              case "NaN":
+                return make_node(AST_NaN, self);
+            }
         }
         return self;
     });
index 4166ac2..997e657 100644 (file)
@@ -331,6 +331,14 @@ AST_Symbol.DEFMETHOD("undeclared", function(){
     return this.definition().undeclared;
 });
 
+AST_LabelRef.DEFMETHOD("undeclared", function(){
+    return false;
+});
+
+AST_Label.DEFMETHOD("undeclared", function(){
+    return false;
+});
+
 AST_Symbol.DEFMETHOD("definition", function(){
     return this.thedef;
 });