aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js70
-rw-r--r--test/compress/issue-1656.js8
-rw-r--r--test/compress/reduce_vars.js30
3 files changed, 77 insertions, 31 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 394184bc..8b6c38dd 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -607,7 +607,13 @@ merge(Compressor.prototype, {
def(AST_Call, function(tw, descend) {
tw.find_parent(AST_Scope).may_call_this();
var exp = this.expression;
- if (exp instanceof AST_SymbolRef) {
+ if (exp instanceof AST_Function) {
+ this.args.forEach(function(arg) {
+ arg.walk(tw);
+ });
+ exp.walk(tw);
+ return true;
+ } else if (exp instanceof AST_SymbolRef) {
var def = exp.definition();
if (this.TYPE == "Call" && tw.in_boolean_context()) def.bool_fn++;
if (!(def.fixed instanceof AST_Defun)) return;
@@ -706,23 +712,20 @@ merge(Compressor.prototype, {
return true;
});
def(AST_Function, function(tw, descend, compressor) {
- var node = this;
- node.inlined = false;
- push(tw);
- reset_variables(tw, compressor, node);
+ var fn = this;
+ fn.inlined = false;
var iife;
- if (!node.name
- && (iife = tw.parent()) instanceof AST_Call
- && iife.expression === node) {
+ if (!fn.name && (iife = tw.parent()) instanceof AST_Call && iife.expression === fn) {
+ reset_variables(tw, compressor, fn);
// Virtually turn IIFE parameters into variable definitions:
// (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
// So existing transformation rules can work on them.
- node.argnames.forEach(function(arg, i) {
+ fn.argnames.forEach(function(arg, i) {
var d = arg.definition();
- if (d.fixed === undefined && (!node.uses_arguments || tw.has_directive("use strict"))) {
+ if (d.fixed === undefined && (!fn.uses_arguments || tw.has_directive("use strict"))) {
var value = iife.args[i];
d.fixed = function() {
- var j = node.argnames.indexOf(arg);
+ var j = fn.argnames.indexOf(arg);
if (j < 0) return value;
return iife.args[j] || make_node(AST_Undefined, iife);
};
@@ -732,10 +735,29 @@ merge(Compressor.prototype, {
d.fixed = false;
}
});
+ var has_return = false;
+ var visit = tw.visit;
+ tw.visit = function(node, descend) {
+ var ret = visit.call(tw, node, descend);
+ if (!has_return && node instanceof AST_Return && tw.find_parent(AST_Scope) === fn) {
+ has_return = true;
+ push(tw);
+ }
+ return ret;
+ };
+ descend();
+ tw.visit = visit;
+ var safe_ids = tw.safe_ids;
+ pop(tw);
+ walk_defuns(tw, fn);
+ if (!has_return) tw.safe_ids = safe_ids;
+ } else {
+ push(tw);
+ reset_variables(tw, compressor, fn);
+ descend();
+ pop(tw);
+ walk_defuns(tw, fn);
}
- descend();
- pop(tw);
- walk_defuns(tw, node);
return true;
});
def(AST_If, function(tw) {
@@ -4512,17 +4534,15 @@ merge(Compressor.prototype, {
}
function scan_ref_scoped(node, descend, init) {
- if (scope === self) {
- if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
- var node_def = node.left.definition();
- if (node.operator != "=") chained[node_def.id] = true;
- match_assigns(node_def, node);
- }
- if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) {
- var node_def = node.expression.definition();
- chained[node_def.id] = true;
- match_assigns(node_def, node);
- }
+ if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
+ var node_def = node.left.definition();
+ if (node.operator != "=") chained[node_def.id] = true;
+ match_assigns(node_def, node);
+ }
+ if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) {
+ var node_def = node.expression.definition();
+ chained[node_def.id] = true;
+ match_assigns(node_def, node);
}
var node_def, props = [], sym = assign_as_unused(node, props);
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
diff --git a/test/compress/issue-1656.js b/test/compress/issue-1656.js
index e44e2094..146ec609 100644
--- a/test/compress/issue-1656.js
+++ b/test/compress/issue-1656.js
@@ -35,11 +35,7 @@ f7: {
console.log(a, b);
}
expect_exact: [
- "var b = 10;",
- "",
- "!function() {",
- " b = 100;",
- "}(), console.log(100, b);",
+ "console.log(100, 100);",
]
- expect_stdout: true
+ expect_stdout: "100 100"
}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 8cc301cc..6cc575f1 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -6976,3 +6976,33 @@ issue_3774: {
}
expect_stdout: "PASS"
}
+
+flatten_iife: {
+ options = {
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = "FAIL";
+ while (!console);
+ a++;
+ (function() {
+ while (!console);
+ a = "PASS";
+ })();
+ console.log(a);
+ }
+ expect: {
+ var a;
+ while (!console);
+ 0;
+ (function() {
+ while (!console);
+ a = "PASS";
+ })();
+ console.log(a);
+ }
+ expect_stdout: "PASS"
+}