From dde5b22b5e99d4a75c8918659b7f73abed436ce2 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Tue, 2 Oct 2012 13:20:07 +0300 Subject: [PATCH] support defines --- bin/uglifyjs2 | 9 ++++++- lib/compress.js | 71 ++++++++++++++++++++++++++----------------------- lib/scope.js | 8 ++++++ 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/bin/uglifyjs2 b/bin/uglifyjs2 index ea82ddfb..63eba7cc 100755 --- a/bin/uglifyjs2 +++ b/bin/uglifyjs2 @@ -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 }; diff --git a/lib/compress.js b/lib/compress.js index ecd9c955..d790a284 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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; }); diff --git a/lib/scope.js b/lib/scope.js index 4166ac25..997e6575 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -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; }); -- 2.34.1