aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js135
-rw-r--r--test/compress/conditionals.js2
-rw-r--r--test/compress/drop-unused.js1
-rw-r--r--test/compress/issue-1639.js6
4 files changed, 100 insertions, 44 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 3aa9f0bc..872e2bbf 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -5222,50 +5222,53 @@ merge(Compressor.prototype, {
self.body = self.alternative || make_node(AST_EmptyStatement, self);
self.alternative = tmp;
}
- if (self.body instanceof AST_SimpleStatement
- && self.alternative instanceof AST_SimpleStatement) {
- return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Conditional, self, {
- condition : self.condition,
- consequent : self.body.body,
- alternative : self.alternative.body
- })
- }).optimize(compressor);
- }
- if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
- if (self_condition_length === negated_length && !negated_is_best
- && self.condition instanceof AST_Binary && self.condition.operator == "||") {
- // although the code length of self.condition and negated are the same,
- // negated does not require additional surrounding parentheses.
- // see https://github.com/mishoo/UglifyJS2/issues/979
- negated_is_best = true;
- }
- if (negated_is_best) return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "||",
- left : negated,
- right : self.body.body
- }).transform(compressor)
- }).optimize(compressor);
- return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "&&",
- left : self.condition,
- right : self.body.body
- }).transform(compressor)
+ var body = [], var_defs = [], refs = [];
+ var body_exprs = sequencesize(self.body, body, var_defs, refs);
+ var alt_exprs = sequencesize(self.alternative, body, var_defs, refs);
+ if (body_exprs && alt_exprs) {
+ if (var_defs.length > 0) body.push(make_node(AST_Var, self, {
+ definitions: var_defs
+ }));
+ if (body_exprs.length == 0) {
+ body.push(make_node(AST_SimpleStatement, self.condition, {
+ body: alt_exprs.length > 0 ? make_node(AST_Binary, self, {
+ operator : "||",
+ left : self.condition,
+ right : make_sequence(self.alternative, alt_exprs)
+ }).transform(compressor) : self.condition.clone()
+ }).optimize(compressor));
+ } else if (alt_exprs.length == 0) {
+ if (self_condition_length === negated_length && !negated_is_best
+ && self.condition instanceof AST_Binary && self.condition.operator == "||") {
+ // although the code length of self.condition and negated are the same,
+ // negated does not require additional surrounding parentheses.
+ // see https://github.com/mishoo/UglifyJS2/issues/979
+ negated_is_best = true;
+ }
+ body.push(make_node(AST_SimpleStatement, self, {
+ body: make_node(AST_Binary, self, {
+ operator : negated_is_best ? "||" : "&&",
+ left : negated_is_best ? negated : self.condition,
+ right : make_sequence(self.body, body_exprs)
+ }).transform(compressor)
+ }).optimize(compressor));
+ } else {
+ body.push(make_node(AST_SimpleStatement, self, {
+ body: make_node(AST_Conditional, self, {
+ condition : self.condition,
+ consequent : make_sequence(self.body, body_exprs),
+ alternative : make_sequence(self.alternative, alt_exprs)
+ })
+ }).optimize(compressor));
+ }
+ refs.forEach(function(ref) {
+ ref.definition().references.push(ref);
+ });
+ return make_node(AST_BlockStatement, self, {
+ body: body
}).optimize(compressor);
}
if (is_empty(self.body)) {
- if (is_empty(self.alternative)) return make_node(AST_SimpleStatement, self.condition, {
- body: self.condition.clone()
- }).optimize(compressor);
- if (self.alternative instanceof AST_SimpleStatement) return make_node(AST_SimpleStatement, self, {
- body: make_node(AST_Binary, self, {
- operator : "||",
- left : self.condition,
- right : self.alternative.body
- }).transform(compressor)
- }).optimize(compressor);
self = make_node(AST_If, self, {
condition: negated,
body: self.alternative,
@@ -5320,6 +5323,56 @@ merge(Compressor.prototype, {
}
if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative);
return self;
+
+ function sequencesize(stat, defuns, var_defs, refs) {
+ if (stat == null) return [];
+ if (stat instanceof AST_BlockStatement) {
+ var exprs = [];
+ for (var i = 0; i < stat.body.length; i++) {
+ var line = stat.body[i];
+ if (line instanceof AST_Defun) {
+ defuns.push(line);
+ } else if (line instanceof AST_EmptyStatement) {
+ continue;
+ } else if (line instanceof AST_SimpleStatement) {
+ if (!compressor.option("sequences") && exprs.length > 0) return;
+ exprs.push(line.body);
+ } else if (line instanceof AST_Var) {
+ if (!compressor.option("sequences") && exprs.length > 0) return;
+ line.definitions.forEach(process_var_def);
+ } else {
+ return;
+ }
+ }
+ return exprs;
+ }
+ if (stat instanceof AST_Defun) {
+ defuns.push(stat);
+ return [];
+ }
+ if (stat instanceof AST_EmptyStatement) return [];
+ if (stat instanceof AST_SimpleStatement) return [ stat.body ];
+ if (stat instanceof AST_Var) {
+ var exprs = [];
+ stat.definitions.forEach(process_var_def);
+ return exprs;
+ }
+
+ function process_var_def(var_def) {
+ var_defs.push(make_node(AST_VarDef, var_def, {
+ name: var_def.name,
+ value: null
+ }));
+ if (!var_def.value) return;
+ var ref = make_node(AST_SymbolRef, var_def.name, var_def.name);
+ exprs.push(make_node(AST_Assign, var_def, {
+ operator: "=",
+ left: ref,
+ right: var_def.value
+ }));
+ refs.push(ref);
+ }
+ }
});
OPT(AST_Switch, function(self, compressor) {
diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js
index c4ae9095..b78f7267 100644
--- a/test/compress/conditionals.js
+++ b/test/compress/conditionals.js
@@ -1384,7 +1384,7 @@ hoist_decl: {
}
expect: {
var a, b;
- x() ? y() : z();
+ (x() ? y : z)();
}
}
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 0f4c6dc6..38f132bf 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -1173,6 +1173,7 @@ var_catch_toplevel: {
x();
} catch (a) {
var a;
+ var a;
}
}();
}
diff --git a/test/compress/issue-1639.js b/test/compress/issue-1639.js
index 1579e06e..6633eb2d 100644
--- a/test/compress/issue-1639.js
+++ b/test/compress/issue-1639.js
@@ -22,8 +22,10 @@ issue_1639_1: {
console.log(a, b);
}
expect: {
- for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
- if (--b, 0) var ignore = 0;
+ for (var a = 100, b = 10, L1 = 5; --L1 > 0;) {
+ var ignore;
+ --b;
+ }
console.log(a, b);
}
expect_stdout: "100 6"