diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-11-16 04:37:37 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-16 04:37:37 +0800 |
commit | ebe761cad09343e514a7a02b591dbb93f651c888 (patch) | |
tree | 1ced0f19779dc07d72800f535f319af4c8e7ba74 | |
parent | fa7a7c5c5aab369f6bcb11fbd9820e80ef0f2528 (diff) | |
download | tracifyjs-ebe761cad09343e514a7a02b591dbb93f651c888.tar.gz tracifyjs-ebe761cad09343e514a7a02b591dbb93f651c888.zip |
minor consolidations (#2484)
- unique symbol generation
- `unsafe` on `AST_Call`
-rw-r--r-- | lib/compress.js | 252 |
1 files changed, 131 insertions, 121 deletions
diff --git a/lib/compress.js b/lib/compress.js index a50dd52b..0f72404f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2778,18 +2778,29 @@ merge(Compressor.prototype, { return self; }); + AST_Scope.DEFMETHOD("make_var_name", function(prefix) { + var var_names = this.var_names; + if (!var_names) { + this.var_names = var_names = Object.create(null); + this.enclosed.forEach(function(def) { + var_names[def.name] = true; + }); + this.variables.each(function(def, name) { + var_names[name] = true; + }); + } + prefix = prefix.replace(/[^a-z_$]+/ig, "_"); + var name = prefix; + for (var i = 0; var_names[name]; i++) name = prefix + "$" + i; + var_names[name] = true; + return name; + }); + AST_Scope.DEFMETHOD("hoist_properties", function(compressor){ var self = this; if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self; var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; var defs_by_id = Object.create(null); - var var_names = Object.create(null); - self.enclosed.forEach(function(def) { - var_names[def.name] = true; - }); - self.variables.each(function(def, name) { - var_names[name] = true; - }); return self.transform(new TreeTransformer(function(node) { if (node instanceof AST_VarDef) { var sym = node.name, def, value; @@ -2829,17 +2840,13 @@ merge(Compressor.prototype, { } function make_sym(key) { - var prefix = sym.name + "_" + key.toString().replace(/[^a-z_$]+/ig, "_"); - var name = prefix; - for (var i = 0; var_names[name]; i++) name = prefix + "$" + i; var new_var = make_node(sym.CTOR, sym, { - name: name, + name: self.make_var_name(sym.name + "_" + key), scope: self }); var def = self.def_variable(new_var); defs.set(key, def); self.enclosed.push(def); - var_names[name] = true; return new_var; } })); @@ -3408,130 +3415,133 @@ merge(Compressor.prototype, { self.args.length = last; } if (compressor.option("unsafe")) { - if (is_undeclared_ref(exp)) { - switch (exp.name) { - case "Array": - if (self.args.length != 1) { - return make_node(AST_Array, self, { - elements: self.args - }).optimize(compressor); - } - break; - case "Object": - if (self.args.length == 0) { - return make_node(AST_Object, self, { - properties: [] - }); - } - break; - case "String": - if (self.args.length == 0) return make_node(AST_String, self, { - value: "" - }); - if (self.args.length <= 1) return make_node(AST_Binary, self, { - left: self.args[0], - operator: "+", - right: make_node(AST_String, self, { value: "" }) + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + if (self.args.length != 1) { + return make_node(AST_Array, self, { + elements: self.args }).optimize(compressor); - break; - case "Number": - if (self.args.length == 0) return make_node(AST_Number, self, { - value: 0 + } + break; + case "Object": + if (self.args.length == 0) { + return make_node(AST_Object, self, { + properties: [] }); - if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + } + break; + case "String": + if (self.args.length == 0) return make_node(AST_String, self, { + value: "" + }); + if (self.args.length <= 1) return make_node(AST_Binary, self, { + left: self.args[0], + operator: "+", + right: make_node(AST_String, self, { value: "" }) + }).optimize(compressor); + break; + case "Number": + if (self.args.length == 0) return make_node(AST_Number, self, { + value: 0 + }); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "+" + }).optimize(compressor); + case "Boolean": + if (self.args.length == 0) return make_node(AST_False, self); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: make_node(AST_UnaryPrefix, self, { expression: self.args[0], - operator: "+" - }).optimize(compressor); - case "Boolean": - if (self.args.length == 0) return make_node(AST_False, self); - if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { - expression: make_node(AST_UnaryPrefix, self, { - expression: self.args[0], - operator: "!" - }), operator: "!" - }).optimize(compressor); - break; - } - } - else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) { - return make_node(AST_Binary, self, { + }), + operator: "!" + }).optimize(compressor); + break; + } else if (exp instanceof AST_Dot) switch(exp.property) { + case "toString": + if (self.args.length == 0) return make_node(AST_Binary, self, { left: make_node(AST_String, self, { value: "" }), operator: "+", right: exp.expression }).optimize(compressor); - } - else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: { - var separator; - if (self.args.length > 0) { - separator = self.args[0].evaluate(compressor); - if (separator === self.args[0]) break EXIT; // not a constant - } - var elements = []; - var consts = []; - exp.expression.elements.forEach(function(el) { - var value = el.evaluate(compressor); - if (value !== el) { - consts.push(value); - } else { - if (consts.length > 0) { - elements.push(make_node(AST_String, self, { - value: consts.join(separator) - })); - consts.length = 0; - } - elements.push(el); - } - }); - if (consts.length > 0) { - elements.push(make_node(AST_String, self, { - value: consts.join(separator) - })); - } - if (elements.length == 0) return make_node(AST_String, self, { value: "" }); - if (elements.length == 1) { - if (elements[0].is_string(compressor)) { - return elements[0]; + break; + case "join": + if (exp.expression instanceof AST_Array) EXIT: { + var separator; + if (self.args.length > 0) { + separator = self.args[0].evaluate(compressor); + if (separator === self.args[0]) break EXIT; // not a constant } - return make_node(AST_Binary, elements[0], { - operator : "+", - left : make_node(AST_String, self, { value: "" }), - right : elements[0] + var elements = []; + var consts = []; + exp.expression.elements.forEach(function(el) { + var value = el.evaluate(compressor); + if (value !== el) { + consts.push(value); + } else { + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); + consts.length = 0; + } + elements.push(el); + } }); - } - if (separator == "") { - var first; - if (elements[0].is_string(compressor) - || elements[1].is_string(compressor)) { - first = elements.shift(); - } else { - first = make_node(AST_String, self, { value: "" }); + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); } - return elements.reduce(function(prev, el){ - return make_node(AST_Binary, el, { + if (elements.length == 0) return make_node(AST_String, self, { value: "" }); + if (elements.length == 1) { + if (elements[0].is_string(compressor)) { + return elements[0]; + } + return make_node(AST_Binary, elements[0], { operator : "+", - left : prev, - right : el + left : make_node(AST_String, self, { value: "" }), + right : elements[0] }); - }, first).optimize(compressor); + } + if (separator == "") { + var first; + if (elements[0].is_string(compressor) + || elements[1].is_string(compressor)) { + first = elements.shift(); + } else { + first = make_node(AST_String, self, { value: "" }); + } + return elements.reduce(function(prev, el){ + return make_node(AST_Binary, el, { + operator : "+", + left : prev, + right : el + }); + }, first).optimize(compressor); + } + // need this awkward cloning to not affect original element + // best_of will decide which one to get through. + var node = self.clone(); + node.expression = node.expression.clone(); + node.expression.expression = node.expression.expression.clone(); + node.expression.expression.elements = elements; + return best_of(compressor, self, node); } - // need this awkward cloning to not affect original element - // best_of will decide which one to get through. - var node = self.clone(); - node.expression = node.expression.clone(); - node.expression.expression = node.expression.expression.clone(); - node.expression.expression.elements = elements; - return best_of(compressor, self, node); - } - else if (exp instanceof AST_Dot && exp.expression.is_string(compressor) && exp.property == "charAt") { - var arg = self.args[0]; - var index = arg ? arg.evaluate(compressor) : 0; - if (index !== arg) { - return make_node(AST_Sub, exp, { - expression: exp.expression, - property: make_node_from_constant(index | 0, arg || exp) - }).optimize(compressor); + break; + case "charAt": + if (exp.expression.is_string(compressor)) { + var arg = self.args[0]; + var index = arg ? arg.evaluate(compressor) : 0; + if (index !== arg) { + return make_node(AST_Sub, exp, { + expression: exp.expression, + property: make_node_from_constant(index | 0, arg || exp) + }).optimize(compressor); + } } + break; } } if (compressor.option("unsafe_Func") |