enhance conditionals (#3798)

This commit is contained in:
Alex Lam S.L
2020-04-18 15:32:22 +01:00
committed by GitHub
parent 60d4e7b09f
commit fd6144d95b
4 changed files with 99 additions and 43 deletions

View File

@@ -5222,50 +5222,53 @@ merge(Compressor.prototype, {
self.body = self.alternative || make_node(AST_EmptyStatement, self); self.body = self.alternative || make_node(AST_EmptyStatement, self);
self.alternative = tmp; self.alternative = tmp;
} }
if (self.body instanceof AST_SimpleStatement var body = [], var_defs = [], refs = [];
&& self.alternative instanceof AST_SimpleStatement) { var body_exprs = sequencesize(self.body, body, var_defs, refs);
return make_node(AST_SimpleStatement, self, { var alt_exprs = sequencesize(self.alternative, body, var_defs, refs);
body: make_node(AST_Conditional, self, { if (body_exprs && alt_exprs) {
condition : self.condition, if (var_defs.length > 0) body.push(make_node(AST_Var, self, {
consequent : self.body.body, definitions: var_defs
alternative : self.alternative.body }));
}) if (body_exprs.length == 0) {
}).optimize(compressor); body.push(make_node(AST_SimpleStatement, self.condition, {
} body: alt_exprs.length > 0 ? make_node(AST_Binary, self, {
if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { operator : "||",
if (self_condition_length === negated_length && !negated_is_best left : self.condition,
&& self.condition instanceof AST_Binary && self.condition.operator == "||") { right : make_sequence(self.alternative, alt_exprs)
// although the code length of self.condition and negated are the same, }).transform(compressor) : self.condition.clone()
// negated does not require additional surrounding parentheses. }).optimize(compressor));
// see https://github.com/mishoo/UglifyJS2/issues/979 } else if (alt_exprs.length == 0) {
negated_is_best = true; 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));
} }
if (negated_is_best) return make_node(AST_SimpleStatement, self, { refs.forEach(function(ref) {
body: make_node(AST_Binary, self, { ref.definition().references.push(ref);
operator : "||", });
left : negated, return make_node(AST_BlockStatement, self, {
right : self.body.body 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)
}).optimize(compressor); }).optimize(compressor);
} }
if (is_empty(self.body)) { 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, { self = make_node(AST_If, self, {
condition: negated, condition: negated,
body: self.alternative, body: self.alternative,
@@ -5320,6 +5323,56 @@ merge(Compressor.prototype, {
} }
if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative); if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative);
return self; 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) { OPT(AST_Switch, function(self, compressor) {

View File

@@ -1384,7 +1384,7 @@ hoist_decl: {
} }
expect: { expect: {
var a, b; var a, b;
x() ? y() : z(); (x() ? y : z)();
} }
} }

View File

@@ -1173,6 +1173,7 @@ var_catch_toplevel: {
x(); x();
} catch (a) { } catch (a) {
var a; var a;
var a;
} }
}(); }();
} }

View File

@@ -22,8 +22,10 @@ issue_1639_1: {
console.log(a, b); console.log(a, b);
} }
expect: { expect: {
for (var a = 100, b = 10, L1 = 5; --L1 > 0;) for (var a = 100, b = 10, L1 = 5; --L1 > 0;) {
if (--b, 0) var ignore = 0; var ignore;
--b;
}
console.log(a, b); console.log(a, b);
} }
expect_stdout: "100 6" expect_stdout: "100 6"