aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-11-16 10:04:30 +0800
committerGitHub <noreply@github.com>2017-11-16 10:04:30 +0800
commitae28a24c7f7919d8de1c3044f28571ebe2036850 (patch)
treeddcc46bb6e6acd01685507b1b735b7bb7c082f33
parentebe761cad09343e514a7a02b591dbb93f651c888 (diff)
downloadtracifyjs-ae28a24c7f7919d8de1c3044f28571ebe2036850.tar.gz
tracifyjs-ae28a24c7f7919d8de1c3044f28571ebe2036850.zip
fix cross-scope inlining of `AST_Function`s (#2486)
fixes #2485
-rwxr-xr-xbin/uglifyjs2
-rw-r--r--lib/ast.js4
-rw-r--r--lib/compress.js13
-rw-r--r--test/compress/reduce_vars.js48
4 files changed, 61 insertions, 6 deletions
diff --git a/bin/uglifyjs b/bin/uglifyjs
index 8cbb3cad..04c402d3 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -15,7 +15,7 @@ var path = require("path");
var program = require("commander");
var UglifyJS = require("../tools/node");
-var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
+var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
var files = {};
var options = {
compress: false,
diff --git a/lib/ast.js b/lib/ast.js
index 9b243f16..a2aa2b40 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -352,11 +352,11 @@ var AST_Accessor = DEFNODE("Accessor", null, {
$documentation: "A setter/getter function. The `name` property is always null."
}, AST_Lambda);
-var AST_Function = DEFNODE("Function", null, {
+var AST_Function = DEFNODE("Function", "inlined", {
$documentation: "A function expression"
}, AST_Lambda);
-var AST_Defun = DEFNODE("Defun", null, {
+var AST_Defun = DEFNODE("Defun", "inlined", {
$documentation: "A function definition"
}, AST_Lambda);
diff --git a/lib/compress.js b/lib/compress.js
index 0f72404f..2577643b 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -373,6 +373,7 @@ merge(Compressor.prototype, {
}
}
if (node instanceof AST_Defun) {
+ node.inlined = false;
var d = node.name.definition();
if (compressor.exposed(d) || safe_to_read(d)) {
d.fixed = false;
@@ -389,6 +390,7 @@ merge(Compressor.prototype, {
return true;
}
if (node instanceof AST_Function) {
+ node.inlined = false;
push();
var iife;
if (!node.name
@@ -4329,16 +4331,21 @@ merge(Compressor.prototype, {
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
}
if (d.single_use && fixed instanceof AST_Function) {
- if (!compressor.option("reduce_funcs") && d.scope !== self.scope) {
+ if (d.scope !== self.scope
+ && (!compressor.option("reduce_funcs")
+ || d.escaped
+ || fixed.inlined)) {
d.single_use = false;
- } else if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {
+ } else if (recursive_ref(compressor, d)) {
d.single_use = false;
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
d.single_use = fixed.is_constant_expression(self.scope);
if (d.single_use == "f") {
var scope = self.scope;
do {
- if (scope.name) scope.name.definition().single_use = false;
+ if (scope instanceof AST_Defun || scope instanceof AST_Function) {
+ scope.inlined = true;
+ }
} while (scope = scope.parent_scope);
}
}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index e7189492..02ff5e43 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -4477,3 +4477,51 @@ perf_8: {
}
expect_stdout: "348150"
}
+
+issue_2485: {
+ options = {
+ reduce_funcs: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ var foo = function(bar) {
+ var n = function(a, b) {
+ return a + b;
+ };
+ var sumAll = function(arg) {
+ return arg.reduce(n, 0);
+ };
+ var runSumAll = function(arg) {
+ return sumAll(arg);
+ };
+ bar.baz = function(arg) {
+ var n = runSumAll(arg);
+ return (n.get = 1), n;
+ };
+ return bar;
+ };
+ var bar = foo({});
+ console.log(bar.baz([1, 2, 3]));
+ }
+ expect: {
+ var foo = function(bar) {
+ var n = function(a, b) {
+ return a + b;
+ };
+ var runSumAll = function(arg) {
+ return function(arg) {
+ return arg.reduce(n, 0);
+ }(arg);
+ };
+ bar.baz = function(arg) {
+ var n = runSumAll(arg);
+ return (n.get = 1), n;
+ };
+ return bar;
+ };
+ var bar = foo({});
+ console.log(bar.baz([1, 2, 3]));
+ }
+ expect_stdout: "6"
+}