enhance dead_code (#5014)

This commit is contained in:
Alex Lam S.L
2021-06-20 08:30:04 +01:00
committed by GitHub
parent 7880568d15
commit fd8dec61ad
3 changed files with 231 additions and 27 deletions

View File

@@ -1714,6 +1714,15 @@ merge(Compressor.prototype, {
return stat instanceof AST_LambdaDefinition;
}
function is_last_statement(body, stat) {
var index = body.lastIndexOf(stat);
if (index < 0) return false;
while (++index < body.length) {
if (!is_declaration(body[index], true)) return false;
}
return true;
}
function tighten_body(statements, compressor) {
var in_loop, in_try, scope;
find_loop_scope_try();
@@ -3168,15 +3177,6 @@ merge(Compressor.prototype, {
return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
}
function is_last_statement(body, stat) {
var index = body.lastIndexOf(stat);
if (index < 0) return false;
while (++index < body.length) {
if (!is_declaration(body[index], true)) return false;
}
return true;
}
function last_of(predicate) {
var block = self, stat, level = 0;
do {
@@ -11140,28 +11140,36 @@ merge(Compressor.prototype, {
if (node instanceof AST_PropAccess) return true;
if (!found && node instanceof AST_SymbolRef && node.definition() === def) {
if (in_try(level, parent)) return true;
def.fixed = false;
found = true;
}
})) break;
if (found) return strip_assignment();
} else if (parent instanceof AST_Exit) {
if (!found) continue;
return strip_assignment(def);
}
if (parent instanceof AST_Exit) {
if (!local) break;
if (in_try(level, parent)) break;
if (is_reachable(scope, [ def ])) break;
def.fixed = false;
return strip_assignment();
} else if (parent instanceof AST_VarDef) {
return strip_assignment(def);
}
if (parent instanceof AST_SimpleStatement) {
if (!local) break;
if (is_reachable(scope, [ def ])) break;
var stat;
do {
stat = parent;
parent = compressor.parent(level++);
if (parent === scope && is_last_statement(parent.body, stat)) return strip_assignment(def);
} while (is_tail_block(stat, parent));
break;
}
if (parent instanceof AST_VarDef) {
if (!(parent.name instanceof AST_SymbolDeclaration)) continue;
if (parent.name.definition() !== def) continue;
if (in_try(level, parent)) break;
def.fixed = false;
return strip_assignment();
return strip_assignment(def);
}
} while (parent instanceof AST_Binary && parent.right === node
|| parent instanceof AST_Conditional && parent.condition !== node
|| parent instanceof AST_Sequence && parent.tail_node() === node
|| parent instanceof AST_UnaryPrefix);
} while (is_tail(node, parent));
}
}
if (compressor.option("sequences")) {
@@ -11206,26 +11214,55 @@ merge(Compressor.prototype, {
}
return try_evaluate(compressor, self);
function is_tail(node, parent) {
if (parent instanceof AST_Binary) {
return parent.right === node || parent.right.is_constant_expression(scope);
}
if (parent instanceof AST_Conditional) {
return parent.condition !== node
|| parent.consequent.is_constant_expression(scope)
&& parent.alternative.is_constant_expression(scope);
}
if (parent instanceof AST_Sequence) {
var exprs = parent.expressions;
var stop = exprs.indexOf(node);
if (stop < 0) return false;
for (var i = exprs.length; --i > stop;) {
if (!exprs[i].is_constant_expression(scope)) return false;
}
return true;
}
if (parent instanceof AST_UnaryPrefix) return true;
}
function is_tail_block(stat, parent) {
if (parent instanceof AST_BlockStatement) return is_last_statement(parent.body, stat);
if (parent instanceof AST_Catch) return is_last_statement(parent.body, stat);
if (parent instanceof AST_Finally) return is_last_statement(parent.body, stat);
if (parent instanceof AST_If) return parent.body === stat || parent.alternative === stat;
if (parent instanceof AST_Try) return parent.bfinally ? parent.bfinally === stat : parent.bcatch === stat;
}
function in_try(level, node) {
var right = self.right;
self.right = make_node(AST_Null, right);
var may_throw = node.may_throw(compressor);
self.right = right;
var parent;
while (parent = compressor.parent(level++)) {
for (var parent; parent = compressor.parent(level++); node = parent) {
if (parent === scope) return false;
if (parent instanceof AST_Try) {
if (parent.bfinally) return true;
if (may_throw && parent.bcatch) return true;
if (parent.bfinally && parent.bfinally !== node) return true;
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
}
}
}
function strip_assignment() {
function strip_assignment(def) {
if (def) def.fixed = false;
return (self.operator != "=" ? make_node(AST_Binary, self, {
operator: self.operator.slice(0, -1),
left: self.left,
right: self.right
right: self.right,
}) : maintain_this_binding(compressor, compressor.parent(), self, self.right)).optimize(compressor);
}
});