aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-04-10 02:46:38 +0800
committerGitHub <noreply@github.com>2018-04-10 02:46:38 +0800
commit183da16896513c22b73d219affebeb155fb8ecdf (patch)
tree89dcb07c7f71b43e5af0b3c6199ccdb80e2f6afb
parent87857b0f1bcb428d36cf715d8ac218eebed6a3ff (diff)
downloadtracifyjs-183da16896513c22b73d219affebeb155fb8ecdf.tar.gz
tracifyjs-183da16896513c22b73d219affebeb155fb8ecdf.zip
handle `pure_funcs` under `inline` & `reduce_vars` correctly (#3066)
fixes #3065
-rw-r--r--README.md3
-rw-r--r--lib/compress.js12
-rw-r--r--test/compress/pure_funcs.js107
3 files changed, 116 insertions, 6 deletions
diff --git a/README.md b/README.md
index 35859115..92443618 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/lib/compress.js b/lib/compress.js
index ddba6245..73f46326 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -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")
diff --git a/test/compress/pure_funcs.js b/test/compress/pure_funcs.js
index 0df51e5f..56c36dd7 100644
--- a/test/compress/pure_funcs.js
+++ b/test/compress/pure_funcs.js
@@ -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");
+ })();
+ }
+}