aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-11-16 04:37:37 +0800
committerGitHub <noreply@github.com>2017-11-16 04:37:37 +0800
commitebe761cad09343e514a7a02b591dbb93f651c888 (patch)
tree1ced0f19779dc07d72800f535f319af4c8e7ba74
parentfa7a7c5c5aab369f6bcb11fbd9820e80ef0f2528 (diff)
downloadtracifyjs-ebe761cad09343e514a7a02b591dbb93f651c888.tar.gz
tracifyjs-ebe761cad09343e514a7a02b591dbb93f651c888.zip
minor consolidations (#2484)
- unique symbol generation - `unsafe` on `AST_Call`
-rw-r--r--lib/compress.js252
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")