enhance dead_code (#5014)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user