fix AST_Node.optimize() (#1602)
Liberal use of `Compressor.transform()` and `AST_Node.optimize()` presents an issue for look-up operations like `TreeWalker.in_boolean_context()` and `TreeWalker.parent()`. This is an incremental fix such that `AST_Node.optimize()` would now contain the correct stack information when called correctly.
This commit is contained in:
@@ -152,13 +152,14 @@ merge(Compressor.prototype, {
|
||||
was_scope = true;
|
||||
}
|
||||
descend(node, this);
|
||||
node = node.optimize(this);
|
||||
if (was_scope && node instanceof AST_Scope) {
|
||||
node.drop_unused(this);
|
||||
descend(node, this);
|
||||
descend(node, this);
|
||||
var opt = node.optimize(this);
|
||||
if (was_scope && opt instanceof AST_Scope) {
|
||||
opt.drop_unused(this);
|
||||
descend(opt, this);
|
||||
}
|
||||
node._squeezed = true;
|
||||
return node;
|
||||
if (opt === node) opt._squeezed = true;
|
||||
return opt;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -171,8 +172,7 @@ merge(Compressor.prototype, {
|
||||
if (compressor.has_directive("use asm")) return self;
|
||||
var opt = optimizer(self, compressor);
|
||||
opt._optimized = true;
|
||||
if (opt === self) return opt;
|
||||
return opt.transform(compressor);
|
||||
return opt;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -914,7 +914,7 @@ merge(Compressor.prototype, {
|
||||
if (stat instanceof AST_LoopControl) {
|
||||
var lct = compressor.loopcontrol_target(stat.label);
|
||||
if ((stat instanceof AST_Break
|
||||
&& lct instanceof AST_BlockStatement
|
||||
&& !(lct instanceof AST_IterationStatement)
|
||||
&& loop_body(lct) === self) || (stat instanceof AST_Continue
|
||||
&& loop_body(lct) === self)) {
|
||||
if (stat.label) {
|
||||
@@ -1646,8 +1646,8 @@ merge(Compressor.prototype, {
|
||||
return thing && thing.aborts();
|
||||
};
|
||||
(function(def){
|
||||
def(AST_Statement, function(){ return null });
|
||||
def(AST_Jump, function(){ return this });
|
||||
def(AST_Statement, return_null);
|
||||
def(AST_Jump, return_this);
|
||||
function block_aborts(){
|
||||
var n = this.body.length;
|
||||
return n > 0 && aborts(this.body[n - 1]);
|
||||
@@ -2077,14 +2077,6 @@ merge(Compressor.prototype, {
|
||||
// drop_side_effect_free()
|
||||
// remove side-effect-free parts which only affects return value
|
||||
(function(def){
|
||||
function return_this() {
|
||||
return this;
|
||||
}
|
||||
|
||||
function return_null() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Drop side-effect-free elements from an array of expressions.
|
||||
// Returns an array of expressions with side-effects or null
|
||||
// if all elements were dropped. Note: original array may be
|
||||
@@ -2358,7 +2350,7 @@ merge(Compressor.prototype, {
|
||||
extract_declarations_from_unreachable_code(compressor, self.alternative, a);
|
||||
}
|
||||
a.push(self.body);
|
||||
return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
|
||||
return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
|
||||
}
|
||||
} else {
|
||||
compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
||||
@@ -2366,7 +2358,7 @@ merge(Compressor.prototype, {
|
||||
var a = [];
|
||||
extract_declarations_from_unreachable_code(compressor, self.body, a);
|
||||
if (self.alternative) a.push(self.alternative);
|
||||
return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
|
||||
return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2385,8 +2377,8 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
if (is_empty(self.body) && is_empty(self.alternative)) {
|
||||
return make_node(AST_SimpleStatement, self.condition, {
|
||||
body: self.condition
|
||||
}).transform(compressor);
|
||||
body: self.condition.clone()
|
||||
}).optimize(compressor);
|
||||
}
|
||||
if (self.body instanceof AST_SimpleStatement
|
||||
&& self.alternative instanceof AST_SimpleStatement) {
|
||||
@@ -2396,7 +2388,7 @@ merge(Compressor.prototype, {
|
||||
consequent : statement_to_expression(self.body),
|
||||
alternative : statement_to_expression(self.alternative)
|
||||
})
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
}
|
||||
if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
|
||||
if (self_condition_length === negated_length && !negated_is_best
|
||||
@@ -2412,14 +2404,14 @@ merge(Compressor.prototype, {
|
||||
left : negated,
|
||||
right : statement_to_expression(self.body)
|
||||
})
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
return make_node(AST_SimpleStatement, self, {
|
||||
body: make_node(AST_Binary, self, {
|
||||
operator : "&&",
|
||||
left : self.condition,
|
||||
right : statement_to_expression(self.body)
|
||||
})
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
}
|
||||
if (self.body instanceof AST_EmptyStatement
|
||||
&& self.alternative
|
||||
@@ -2430,7 +2422,7 @@ merge(Compressor.prototype, {
|
||||
left : self.condition,
|
||||
right : statement_to_expression(self.alternative)
|
||||
})
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
}
|
||||
if (self.body instanceof AST_Exit
|
||||
&& self.alternative instanceof AST_Exit
|
||||
@@ -2440,18 +2432,21 @@ merge(Compressor.prototype, {
|
||||
condition : self.condition,
|
||||
consequent : self.body.value || make_node(AST_Undefined, self.body),
|
||||
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
|
||||
})
|
||||
}).transform(compressor);
|
||||
}).transform(compressor)
|
||||
}).optimize(compressor);
|
||||
}
|
||||
if (self.body instanceof AST_If
|
||||
&& !self.body.alternative
|
||||
&& !self.alternative) {
|
||||
self.condition = make_node(AST_Binary, self.condition, {
|
||||
operator: "&&",
|
||||
left: self.condition,
|
||||
right: self.body.condition
|
||||
}).transform(compressor);
|
||||
self.body = self.body.body;
|
||||
self = make_node(AST_If, self, {
|
||||
condition: make_node(AST_Binary, self.condition, {
|
||||
operator: "&&",
|
||||
left: self.condition,
|
||||
right: self.body.condition
|
||||
}),
|
||||
body: self.body.body,
|
||||
alternative: null
|
||||
});
|
||||
}
|
||||
if (aborts(self.body)) {
|
||||
if (self.alternative) {
|
||||
@@ -2459,7 +2454,7 @@ merge(Compressor.prototype, {
|
||||
self.alternative = null;
|
||||
return make_node(AST_BlockStatement, self, {
|
||||
body: [ self, alt ]
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
}
|
||||
}
|
||||
if (aborts(self.alternative)) {
|
||||
@@ -2469,7 +2464,7 @@ merge(Compressor.prototype, {
|
||||
self.alternative = null;
|
||||
return make_node(AST_BlockStatement, self, {
|
||||
body: [ self, body ]
|
||||
}).transform(compressor);
|
||||
}).optimize(compressor);
|
||||
}
|
||||
return self;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user