enhance evaluate & reduce_vars (#3870)
This commit is contained in:
@@ -3302,19 +3302,23 @@ merge(Compressor.prototype, {
|
|||||||
var non_converting_unary = makePredicate("! typeof void");
|
var non_converting_unary = makePredicate("! typeof void");
|
||||||
def(AST_UnaryPrefix, function(compressor, ignore_side_effects, cached, depth) {
|
def(AST_UnaryPrefix, function(compressor, ignore_side_effects, cached, depth) {
|
||||||
var e = this.expression;
|
var e = this.expression;
|
||||||
|
var op = this.operator;
|
||||||
// Function would be evaluated to an array and so typeof would
|
// Function would be evaluated to an array and so typeof would
|
||||||
// incorrectly return 'object'. Hence making is a special case.
|
// incorrectly return 'object'. Hence making is a special case.
|
||||||
if (compressor.option("typeofs")
|
if (compressor.option("typeofs")
|
||||||
&& this.operator == "typeof"
|
&& op == "typeof"
|
||||||
&& (e instanceof AST_Lambda
|
&& (e instanceof AST_Lambda
|
||||||
|| e instanceof AST_SymbolRef
|
|| e instanceof AST_SymbolRef
|
||||||
&& e.fixed_value() instanceof AST_Lambda)) {
|
&& e.fixed_value() instanceof AST_Lambda)) {
|
||||||
return typeof function(){};
|
return typeof function(){};
|
||||||
}
|
}
|
||||||
if (!non_converting_unary[this.operator]) depth++;
|
if (!non_converting_unary[op]) depth++;
|
||||||
var v = e._eval(compressor, ignore_side_effects, cached, depth);
|
var v = e._eval(compressor, ignore_side_effects, cached, depth);
|
||||||
if (v === this.expression) return this;
|
if (v === e) {
|
||||||
switch (this.operator) {
|
if (ignore_side_effects && op == "void") return void 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
switch (op) {
|
||||||
case "!": return !v;
|
case "!": return !v;
|
||||||
case "typeof":
|
case "typeof":
|
||||||
// typeof <RegExp> returns "object" or "function" on different platforms
|
// typeof <RegExp> returns "object" or "function" on different platforms
|
||||||
@@ -3330,7 +3334,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!(e instanceof AST_SymbolRef)) return this;
|
if (!(e instanceof AST_SymbolRef)) return this;
|
||||||
var refs = e.definition().references;
|
var refs = e.definition().references;
|
||||||
if (refs[refs.length - 1] !== e) return this;
|
if (refs[refs.length - 1] !== e) return this;
|
||||||
return HOP(e, "_eval") ? +(this.operator[0] + 1) + +v : v;
|
return HOP(e, "_eval") ? +(op[0] + 1) + +v : v;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
@@ -7500,9 +7504,13 @@ merge(Compressor.prototype, {
|
|||||||
init = fixed;
|
init = fixed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var ev = fixed.evaluate(compressor);
|
var ev = fixed.evaluate(compressor, true);
|
||||||
if (ev !== fixed && (!(ev instanceof RegExp)
|
if (ev !== fixed
|
||||||
|| compressor.option("unsafe_regexp") && !def.cross_loop && same_scope(def))) {
|
&& typeof ev != "function"
|
||||||
|
&& (typeof ev != "object"
|
||||||
|
|| ev instanceof RegExp
|
||||||
|
&& compressor.option("unsafe_regexp")
|
||||||
|
&& !def.cross_loop && same_scope(def))) {
|
||||||
init = make_node_from_constant(ev, fixed);
|
init = make_node_from_constant(ev, fixed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -785,11 +785,12 @@ issue_3791_2: {
|
|||||||
|
|
||||||
issue_3795: {
|
issue_3795: {
|
||||||
options = {
|
options = {
|
||||||
|
booleans: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
|
keep_fargs: "strict",
|
||||||
loops: true,
|
loops: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -798,22 +799,21 @@ issue_3795: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = "FAIL";
|
var a = "FAIL";
|
||||||
function f(b) {
|
function f(b, c) {
|
||||||
for (var i = 1; b && i; --i) return 0;
|
for (var i = 5; c && i; --i) return -1;
|
||||||
a = "PASS";
|
a = "PASS";
|
||||||
}
|
}
|
||||||
var c = f(a = "");
|
var d = f(a = 42, d);
|
||||||
console.log(a);
|
console.log(a, d);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "FAIL";
|
var a = "FAIL", d = function() {
|
||||||
(function(b) {
|
if (a = 42, d) return -1;
|
||||||
a = "";
|
|
||||||
a = "PASS";
|
a = "PASS";
|
||||||
})();
|
}();
|
||||||
console.log(a);
|
console.log(a, d);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
if_body: {
|
if_body: {
|
||||||
|
|||||||
@@ -7054,3 +7054,24 @@ issue_3866: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void_side_effects: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = void console.log("PASS");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user