handle pure_funcs under inline & reduce_vars correctly (#3066)

fixes #3065
This commit is contained in:
Alex Lam S.L
2018-04-10 02:46:38 +08:00
committed by GitHub
parent 87857b0f1b
commit 183da16896
3 changed files with 116 additions and 6 deletions

View File

@@ -685,7 +685,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
function won't produce any side effect, in which case the whole
statement would get discarded. The current implementation adds some
overhead (compression will be slower).
overhead (compression will be slower). Make sure symbols under `pure_funcs`
are also under `mangle.reserved` to avoid mangling.
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
this, UglifyJS will assume that object property access

View File

@@ -4573,7 +4573,8 @@ merge(Compressor.prototype, {
}
}
var stat = is_func && fn.body[0];
if (compressor.option("inline") && stat instanceof AST_Return) {
var can_inline = compressor.option("inline") && !self.is_expr_pure(compressor);
if (can_inline && stat instanceof AST_Return) {
var value = stat.value;
if (!value || value.is_constant_expression()) {
if (value) {
@@ -4587,7 +4588,7 @@ merge(Compressor.prototype, {
}
if (is_func) {
var def, value, scope, in_loop, level = -1;
if (compressor.option("inline")
if (can_inline
&& !fn.uses_arguments
&& !fn.uses_eval
&& !(fn.name && fn instanceof AST_Function)
@@ -5460,11 +5461,12 @@ merge(Compressor.prototype, {
return make_node(AST_Infinity, self).optimize(compressor);
}
}
if (compressor.option("reduce_vars")
&& is_lhs(self, compressor.parent()) !== self) {
var parent = compressor.parent();
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
var d = self.definition();
var fixed = self.fixed_value();
var single_use = d.single_use;
var single_use = d.single_use
&& !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
if (single_use && fixed instanceof AST_Lambda) {
if (d.scope !== self.scope
&& (!compressor.option("reduce_funcs")

View File

@@ -535,3 +535,110 @@ issue_2705_6: {
"/* */new(/* */a()||b())(c(),d());",
]
}
issue_3065_1: {
options = {
inline: true,
pure_funcs: [ "pureFunc" ],
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function modifyWrapper(a, f, wrapper) {
wrapper.a = a;
wrapper.f = f;
return wrapper;
}
function pureFunc(fun) {
return modifyWrapper(1, fun, function(a) {
return fun(a);
});
}
var unused = pureFunc(function(x) {
return x;
});
}
expect: {}
}
issue_3065_2: {
rename = true
options = {
inline: true,
pure_funcs: [ "pureFunc" ],
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
mangle = {
reserved: [ "pureFunc" ],
toplevel: true,
}
input: {
function modifyWrapper(a, f, wrapper) {
wrapper.a = a;
wrapper.f = f;
return wrapper;
}
function pureFunc(fun) {
return modifyWrapper(1, fun, function(a) {
return fun(a);
});
}
var unused = pureFunc(function(x) {
return x;
});
}
expect: {}
}
issue_3065_3: {
options = {
pure_funcs: [ "debug" ],
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
function debug(msg) {
console.log(msg);
}
debug(function() {
console.log("PASS");
return "FAIL";
}());
}
expect: {
(function() {
console.log("PASS");
})();
}
}
issue_3065_4: {
options = {
pure_funcs: [ "debug" ],
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var debug = function(msg) {
console.log(msg);
};
debug(function() {
console.log("PASS");
return "FAIL";
}());
}
expect: {
(function() {
console.log("PASS");
})();
}
}