enhance conditionals (#3798)
This commit is contained in:
117
lib/compress.js
117
lib/compress.js
@@ -5222,17 +5222,22 @@ 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) {
|
||||
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,
|
||||
@@ -5240,32 +5245,30 @@ merge(Compressor.prototype, {
|
||||
// see https://github.com/mishoo/UglifyJS2/issues/979
|
||||
negated_is_best = true;
|
||||
}
|
||||
if (negated_is_best) return make_node(AST_SimpleStatement, self, {
|
||||
body.push(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
|
||||
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) {
|
||||
|
||||
@@ -1384,7 +1384,7 @@ hoist_decl: {
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
x() ? y() : z();
|
||||
(x() ? y : z)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1173,6 +1173,7 @@ var_catch_toplevel: {
|
||||
x();
|
||||
} catch (a) {
|
||||
var a;
|
||||
var a;
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user