fold cascade functionality into collapse_vars (#2586)
This commit is contained in:
109
lib/compress.js
109
lib/compress.js
@@ -49,7 +49,6 @@ function Compressor(options, false_by_default) {
|
||||
TreeTransformer.call(this, this.before, this.after);
|
||||
this.options = defaults(options, {
|
||||
booleans : !false_by_default,
|
||||
cascade : !false_by_default,
|
||||
collapse_vars : !false_by_default,
|
||||
comparisons : !false_by_default,
|
||||
conditionals : !false_by_default,
|
||||
@@ -884,6 +883,8 @@ merge(Compressor.prototype, {
|
||||
if (!hit) {
|
||||
if (node === candidate) {
|
||||
hit = true;
|
||||
stop_after = find_stop(node, 0);
|
||||
if (stop_after === node) abort = true;
|
||||
return node;
|
||||
}
|
||||
return;
|
||||
@@ -963,12 +964,13 @@ merge(Compressor.prototype, {
|
||||
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
||||
|| parent instanceof AST_Conditional
|
||||
|| parent instanceof AST_If)) {
|
||||
if (!(node instanceof AST_Scope)) descend(node, scanner);
|
||||
abort = true;
|
||||
return node;
|
||||
stop_after = node;
|
||||
if (node instanceof AST_Scope) abort = true;
|
||||
}
|
||||
// Skip (non-executed) functions
|
||||
if (node instanceof AST_Scope) return node;
|
||||
}, function(node) {
|
||||
if (!abort && stop_after === node) abort = true;
|
||||
});
|
||||
var multi_replacer = new TreeTransformer(function(node) {
|
||||
if (abort) return node;
|
||||
@@ -1003,6 +1005,7 @@ merge(Compressor.prototype, {
|
||||
while (candidates.length > 0) {
|
||||
var candidate = candidates.pop();
|
||||
var value_def = null;
|
||||
var stop_after = null;
|
||||
var lhs = get_lhs(candidate);
|
||||
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
|
||||
// Locate symbols which may execute code outside of scanning range
|
||||
@@ -1094,19 +1097,43 @@ merge(Compressor.prototype, {
|
||||
if (expr instanceof AST_Assign && !expr.left.has_side_effects(compressor)
|
||||
|| expr instanceof AST_Unary && (expr.operator == "++" || expr.operator == "--")) {
|
||||
candidates.push(expr);
|
||||
} else if (expr instanceof AST_Sequence) {
|
||||
expr.expressions.forEach(extract_candidates);
|
||||
} else if (expr instanceof AST_Case) {
|
||||
extract_candidates(expr.expression);
|
||||
} else if (expr instanceof AST_Conditional) {
|
||||
extract_candidates(expr.condition);
|
||||
extract_candidates(expr.consequent);
|
||||
extract_candidates(expr.alternative);
|
||||
} else if (expr instanceof AST_Definitions) {
|
||||
expr.definitions.forEach(function(var_def) {
|
||||
if (var_def.value) candidates.push(var_def);
|
||||
});
|
||||
} else if (expr instanceof AST_Exit) {
|
||||
if (expr.value) extract_candidates(expr.value);
|
||||
} else if (expr instanceof AST_For) {
|
||||
if (expr.init) extract_candidates(expr.init);
|
||||
} else if (expr instanceof AST_If) {
|
||||
extract_candidates(expr.condition);
|
||||
} else if (expr instanceof AST_Sequence) {
|
||||
expr.expressions.forEach(extract_candidates);
|
||||
} else if (expr instanceof AST_SimpleStatement) {
|
||||
extract_candidates(expr.body);
|
||||
} else if (expr instanceof AST_For && expr.init) {
|
||||
extract_candidates(expr.init);
|
||||
} else if (expr instanceof AST_Switch) {
|
||||
extract_candidates(expr.expression);
|
||||
expr.body.forEach(extract_candidates);
|
||||
}
|
||||
}
|
||||
|
||||
function find_stop(node, level) {
|
||||
var parent = scanner.parent(level);
|
||||
if (parent instanceof AST_Case) return node;
|
||||
if (parent instanceof AST_Conditional) return node;
|
||||
if (parent instanceof AST_Exit) return node;
|
||||
if (parent instanceof AST_If) return node;
|
||||
if (parent instanceof AST_Sequence) return find_stop(parent, level + 1);
|
||||
if (parent instanceof AST_Switch) return node;
|
||||
return null;
|
||||
}
|
||||
|
||||
function mangleable_var(var_def) {
|
||||
var value = var_def.value;
|
||||
if (!(value instanceof AST_SymbolRef)) return;
|
||||
@@ -3898,7 +3925,6 @@ merge(Compressor.prototype, {
|
||||
filter_for_side_effects();
|
||||
var end = expressions.length - 1;
|
||||
trim_right_for_undefined();
|
||||
if (end > 0 && compressor.option("cascade")) trim_left_for_assignment();
|
||||
if (end == 0) {
|
||||
self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]);
|
||||
if (!(self instanceof AST_Sequence)) self = self.optimize(compressor);
|
||||
@@ -3929,71 +3955,6 @@ merge(Compressor.prototype, {
|
||||
expressions.length = end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function trim_left_for_assignment() {
|
||||
for (var i = 0, j = 1; j <= end; j++) {
|
||||
var left = expressions[i];
|
||||
var cdr = expressions[j];
|
||||
if (left instanceof AST_Assign
|
||||
&& !left.left.has_side_effects(compressor)) {
|
||||
left = left.left;
|
||||
} else if (left instanceof AST_Unary
|
||||
&& (left.operator == "++" || left.operator == "--")) {
|
||||
left = left.expression;
|
||||
} else left = null;
|
||||
if (!left || is_lhs_read_only(left) || left.has_side_effects(compressor)) {
|
||||
expressions[++i] = cdr;
|
||||
continue;
|
||||
}
|
||||
var parent = null, field;
|
||||
expressions[j] = cdr = cdr.clone();
|
||||
while (true) {
|
||||
if (cdr.equivalent_to(left)) {
|
||||
var car = expressions[i];
|
||||
if (car instanceof AST_UnaryPostfix) {
|
||||
car = make_node(AST_UnaryPrefix, car, {
|
||||
operator: car.operator,
|
||||
expression: left
|
||||
});
|
||||
} else {
|
||||
car.write_only = false;
|
||||
}
|
||||
if (parent) {
|
||||
parent[field] = car;
|
||||
expressions[i] = expressions[j];
|
||||
} else {
|
||||
expressions[i] = car;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) {
|
||||
if (cdr.left.is_constant()) {
|
||||
if (lazy_op(cdr.operator)) {
|
||||
expressions[++i] = expressions[j];
|
||||
break;
|
||||
}
|
||||
field = "right";
|
||||
} else {
|
||||
field = "left";
|
||||
}
|
||||
} else if (cdr instanceof AST_Call
|
||||
&& !(left instanceof AST_PropAccess && cdr.expression.equivalent_to(left))
|
||||
|| cdr instanceof AST_PropAccess
|
||||
|| cdr instanceof AST_Unary && !unary_side_effects(cdr.operator)) {
|
||||
field = "expression";
|
||||
} else if (cdr instanceof AST_Conditional) {
|
||||
field = "condition";
|
||||
} else {
|
||||
expressions[++i] = expressions[j];
|
||||
break;
|
||||
}
|
||||
parent = cdr;
|
||||
cdr = cdr[field] = cdr[field].clone();
|
||||
}
|
||||
}
|
||||
end = i;
|
||||
expressions.length = end + 1;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
|
||||
|
||||
Reference in New Issue
Block a user