enhance evaluate & reduce_vars (#5060)
This commit is contained in:
@@ -734,7 +734,12 @@ merge(Compressor.prototype, {
|
|||||||
var save = fixed;
|
var save = fixed;
|
||||||
if (save) fixed = function() {
|
if (save) fixed = function() {
|
||||||
var value = save();
|
var value = save();
|
||||||
return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node;
|
var ev;
|
||||||
|
if (is_undefined(value, compressor)
|
||||||
|
|| (ev = fuzzy_eval(compressor, value, true)) === undefined) {
|
||||||
|
return make_sequence(node, [ value, node.value ]);
|
||||||
|
}
|
||||||
|
return ev instanceof AST_Node ? node : value;
|
||||||
};
|
};
|
||||||
node.name.walk(scanner);
|
node.name.walk(scanner);
|
||||||
fixed = save;
|
fixed = save;
|
||||||
@@ -7293,7 +7298,7 @@ merge(Compressor.prototype, {
|
|||||||
node.in_bool = true;
|
node.in_bool = true;
|
||||||
var value = node.value;
|
var value = node.value;
|
||||||
if (value) {
|
if (value) {
|
||||||
var ev = value.is_truthy() || value.evaluate(compressor, true);
|
var ev = fuzzy_eval(compressor, value);
|
||||||
if (!ev) {
|
if (!ev) {
|
||||||
value = value.drop_side_effect_free(compressor);
|
value = value.drop_side_effect_free(compressor);
|
||||||
node.value = value ? make_sequence(node.value, [
|
node.value = value ? make_sequence(node.value, [
|
||||||
@@ -8006,7 +8011,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
OPT(AST_Do, function(self, compressor) {
|
OPT(AST_Do, function(self, compressor) {
|
||||||
if (!compressor.option("loops")) return self;
|
if (!compressor.option("loops")) return self;
|
||||||
var cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true);
|
var cond = fuzzy_eval(compressor, self.condition);
|
||||||
if (!(cond instanceof AST_Node)) {
|
if (!(cond instanceof AST_Node)) {
|
||||||
if (cond && !has_loop_control(self, compressor.parent(), AST_Continue)) return make_node(AST_For, self, {
|
if (cond && !has_loop_control(self, compressor.parent(), AST_Continue)) return make_node(AST_For, self, {
|
||||||
body: make_node(AST_BlockStatement, self.body, {
|
body: make_node(AST_BlockStatement, self.body, {
|
||||||
@@ -8174,36 +8179,25 @@ merge(Compressor.prototype, {
|
|||||||
if (self.step) self.step = self.step.drop_side_effect_free(compressor);
|
if (self.step) self.step = self.step.drop_side_effect_free(compressor);
|
||||||
}
|
}
|
||||||
if (self.condition) {
|
if (self.condition) {
|
||||||
var cond = self.condition.evaluate(compressor);
|
var cond = fuzzy_eval(compressor, self.condition);
|
||||||
if (cond instanceof AST_Node) {
|
|
||||||
cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true);
|
|
||||||
} else if (cond) {
|
|
||||||
self.condition = null;
|
|
||||||
}
|
|
||||||
if (!cond) {
|
if (!cond) {
|
||||||
if (compressor.option("dead_code")) {
|
if (compressor.option("dead_code")) {
|
||||||
var body = [];
|
var body = [];
|
||||||
if (is_statement(self.init)) {
|
if (is_statement(self.init)) {
|
||||||
body.push(self.init);
|
body.push(self.init);
|
||||||
} else if (self.init) {
|
} else if (self.init) {
|
||||||
body.push(make_node(AST_SimpleStatement, self.init, {
|
body.push(make_node(AST_SimpleStatement, self.init, { body: self.init }));
|
||||||
body: self.init
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
body.push(make_node(AST_SimpleStatement, self.condition, {
|
body.push(make_node(AST_SimpleStatement, self.condition, { body: self.condition }));
|
||||||
body: self.condition
|
|
||||||
}));
|
|
||||||
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
||||||
return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
|
return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
|
||||||
}
|
}
|
||||||
} else if (self.condition && !(cond instanceof AST_Node)) {
|
} else if (!(cond instanceof AST_Node)) {
|
||||||
self.body = make_node(AST_BlockStatement, self.body, {
|
self.body = make_node(AST_BlockStatement, self.body, {
|
||||||
body: [
|
body: [
|
||||||
make_node(AST_SimpleStatement, self.condition, {
|
make_node(AST_SimpleStatement, self.condition, { body: self.condition }),
|
||||||
body: self.condition
|
self.body,
|
||||||
}),
|
],
|
||||||
self.body
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
self.condition = null;
|
self.condition = null;
|
||||||
}
|
}
|
||||||
@@ -8894,7 +8888,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!compressor.option("optional_chains")) return;
|
if (!compressor.option("optional_chains")) return;
|
||||||
if (!self.optional) return;
|
if (!self.optional) return;
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
var ev = expr.evaluate(compressor, true);
|
var ev = fuzzy_eval(compressor, expr, true);
|
||||||
if (ev == null) return make_node(AST_UnaryPrefix, self, {
|
if (ev == null) return make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "void",
|
operator: "void",
|
||||||
expression: expr,
|
expression: expr,
|
||||||
@@ -10492,7 +10486,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
// (x || false) && y ---> x ? y : false
|
// (x || false) && y ---> x ? y : false
|
||||||
if (self.left.operator == "||") {
|
if (self.left.operator == "||") {
|
||||||
var lr = self.left.right.evaluate(compressor, true);
|
var lr = fuzzy_eval(compressor, self.left.right);
|
||||||
if (!lr) return make_node(AST_Conditional, self, {
|
if (!lr) return make_node(AST_Conditional, self, {
|
||||||
condition: self.left.left,
|
condition: self.left.left,
|
||||||
consequent: self.right,
|
consequent: self.right,
|
||||||
@@ -10545,7 +10539,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
// x && true || y ---> x ? true : y
|
// x && true || y ---> x ? true : y
|
||||||
if (!nullish && self.left.operator == "&&") {
|
if (!nullish && self.left.operator == "&&") {
|
||||||
var lr = self.left.right.is_truthy() || self.left.right.evaluate(compressor, true);
|
var lr = fuzzy_eval(compressor, self.left.right);
|
||||||
if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
|
if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
|
||||||
condition: self.left.left,
|
condition: self.left.left,
|
||||||
consequent: self.left.right,
|
consequent: self.left.right,
|
||||||
@@ -11070,22 +11064,17 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var local = self.fixed !== def.fixed;
|
var local = self.fixed !== def.fixed;
|
||||||
if (fixed && (local || def.should_replace !== false)) {
|
if (fixed && (local || def.should_replace !== false)) {
|
||||||
var init;
|
var ev, init;
|
||||||
if (fixed instanceof AST_This) {
|
if (fixed instanceof AST_This) {
|
||||||
if (!is_funarg(def) && same_scope(def)) {
|
if (!is_funarg(def) && same_scope(def)) init = fixed;
|
||||||
init = fixed;
|
} else if ((ev = fixed.evaluate(compressor, true)) !== fixed
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var ev = fixed.evaluate(compressor, true);
|
|
||||||
if (ev !== fixed
|
|
||||||
&& typeof ev != "function"
|
&& typeof ev != "function"
|
||||||
&& (typeof ev != "object"
|
&& (ev === null
|
||||||
|| ev instanceof RegExp
|
|| typeof ev != "object"
|
||||||
&& compressor.option("unsafe_regexp")
|
|| compressor.option("unsafe_regexp")
|
||||||
&& !def.cross_loop && same_scope(def))) {
|
&& ev instanceof RegExp && !def.cross_loop && same_scope(def))) {
|
||||||
init = make_node_from_constant(ev, fixed);
|
init = make_node_from_constant(ev, fixed);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (init) {
|
if (init) {
|
||||||
if (!local && def.should_replace === undefined) {
|
if (!local && def.should_replace === undefined) {
|
||||||
var value_length = init.optimize(compressor).print_to_string().length;
|
var value_length = init.optimize(compressor).print_to_string().length;
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ process_boolean_returns: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a = console.log("FAIL 1")) {
|
console.log(function(a = console.log("FAIL 1")) {
|
||||||
return a() ? "PASS" : "FAIL 2";
|
return 42 ? "PASS" : "FAIL 2";
|
||||||
}(function() {
|
}(function() {
|
||||||
return 1;
|
return 1;
|
||||||
}));
|
}));
|
||||||
@@ -245,21 +245,64 @@ maintain_if: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
reduce_value: {
|
reduce_funarg: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function(a = "PASS") {
|
console.log(...function(a = "foo", b = "bar", c = "baz") {
|
||||||
return a;
|
return [ a, b, c ];
|
||||||
}());
|
}(void 0, null));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log("PASS");
|
console.log(...function() {
|
||||||
|
return [ "foo", null, "baz" ];
|
||||||
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "foo null baz"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_array: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ a = "foo", b = "bar", c = "baz" ] = [ void 0, null ];
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var [ , , c = "baz" ] = [ void 0, null ];
|
||||||
|
console.log("foo", null, c);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo null baz"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_object: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var { a = "foo", b = "bar", c = "baz" } = { a: void 0, b: null };
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var { c = "baz" } = { a: void 0, b: null };
|
||||||
|
console.log("foo", null, c);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo null baz"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,9 +323,7 @@ issue_4893_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
try{
|
try{
|
||||||
(function f() {
|
(function f() {
|
||||||
var b;
|
null.p += 42;
|
||||||
b = null;
|
|
||||||
b.p += 42;
|
|
||||||
f;
|
f;
|
||||||
})();
|
})();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -1292,6 +1292,7 @@ toplevel_on_loops_3: {
|
|||||||
loops: true,
|
loops: true,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user