aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-07-03 23:19:08 +0100
committerGitHub <noreply@github.com>2021-07-04 06:19:08 +0800
commit972b9f0bef90844a522f777610e88bf113309025 (patch)
tree243cb59938486fdee27ee60fd2c3c77d0ecc48f8
parent668f96623c745a4255766fe5595f1a95052afb77 (diff)
downloadtracifyjs-972b9f0bef90844a522f777610e88bf113309025.tar.gz
tracifyjs-972b9f0bef90844a522f777610e88bf113309025.zip
enhance `functions` & `reduce_vars` (#5045)
-rw-r--r--lib/compress.js331
-rw-r--r--test/compress/arrows.js32
-rw-r--r--test/compress/drop-unused.js3
-rw-r--r--test/compress/functions.js2
-rw-r--r--test/compress/hoist_vars.js3
-rw-r--r--test/compress/let.js35
-rw-r--r--test/compress/pure_getters.js1
-rw-r--r--test/compress/reduce_vars.js37
-rw-r--r--test/reduce.js2
9 files changed, 286 insertions, 160 deletions
diff --git a/lib/compress.js b/lib/compress.js
index ea431f13..8045cecf 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -484,9 +484,21 @@ merge(Compressor.prototype, {
def.single_use = undefined;
}
+ function reset_block_variables(tw, compressor, scope) {
+ scope.variables.each(function(def) {
+ reset_def(tw, compressor, def);
+ });
+ }
+
function reset_variables(tw, compressor, scope) {
+ scope.fn_defs = [];
scope.variables.each(function(def) {
reset_def(tw, compressor, def);
+ var init = def.init;
+ if (init instanceof AST_LambdaDefinition) {
+ scope.fn_defs.push(init);
+ init.safe_ids = null;
+ }
if (def.fixed === null) {
def.safe_ids = tw.safe_ids;
mark(tw, def);
@@ -496,13 +508,7 @@ merge(Compressor.prototype, {
}
});
scope.may_call_this = function() {
- scope.may_call_this = noop;
- if (!scope.contains_this()) return;
- scope.functions.each(function(def) {
- if (def.init instanceof AST_LambdaDefinition && !(def.id in tw.defun_ids)) {
- tw.defun_ids[def.id] = false;
- }
- });
+ scope.may_call_this = scope.contains_this() ? return_true : return_false;
};
if (scope.uses_arguments) scope.each_argname(function(node) {
node.definition().last_ref = false;
@@ -513,39 +519,56 @@ merge(Compressor.prototype, {
});
}
- function mark_defun(tw, def) {
- if (def.id in tw.defun_ids) {
- var marker = tw.defun_ids[def.id];
- if (!marker) return;
- var visited = tw.defun_visited[def.id];
- if (marker === tw.safe_ids) return !visited && def.fixed;
+ function mark_fn_def(tw, def, fn) {
+ if (!HOP(fn, "safe_ids")) return;
+ var marker = fn.safe_ids;
+ if (marker === false) return;
+ if (fn.parent_scope.resolve().may_call_this === return_true) return;
+ if (marker) {
+ var visited = member(fn, tw.fn_visited);
+ if (marker === tw.safe_ids) return !visited && fn;
if (visited) {
- def.init.enclosed.forEach(function(d) {
- if (def.init.variables.get(d.name) === d) return;
- if (!safe_to_read(tw, d)) d.fixed = false;
+ fn.enclosed.forEach(function(d) {
+ if (fn.variables.get(d.name) === d) return;
+ if (safe_to_read(tw, d)) return;
+ d.single_use = false;
+ if (d.fixed instanceof AST_LambdaDefinition) return;
+ d.fixed = false;
});
return;
}
- } else if (!tw.in_loop) {
- var scope = def.scope;
- var s = tw.find_parent(AST_Scope);
- do {
- if (s === scope) {
- tw.defun_ids[def.id] = tw.safe_ids;
- return def.fixed;
- }
- } while (s instanceof AST_LambdaExpression && (s = s.parent_scope.resolve()));
+ } else if (!tw.in_loop && !(tw.fn_scanning && tw.fn_scanning !== def.scope.resolve())) {
+ fn.safe_ids = tw.safe_ids;
+ return fn;
}
- tw.defun_ids[def.id] = false;
+ fn.safe_ids = false;
}
- function walk_defuns(tw, scope) {
- scope.functions.each(function(def) {
- if (def.init instanceof AST_LambdaDefinition && !tw.defun_visited[def.id]) {
- tw.defun_ids[def.id] = tw.safe_ids;
- def.init.walk(tw);
- }
+ function walk_fn_def(tw, fn) {
+ var was_scanning = tw.fn_scanning;
+ tw.fn_scanning = fn;
+ fn.walk(tw);
+ tw.fn_scanning = was_scanning;
+ }
+
+ function pop_scope(tw, scope) {
+ var fn_defs = scope.fn_defs;
+ var tangled = scope.may_call_this === return_true ? fn_defs : fn_defs.filter(function(fn) {
+ if (fn.safe_ids === false) return true;
+ fn.safe_ids = tw.safe_ids;
+ walk_fn_def(tw, fn);
+ return false;
});
+ pop(tw);
+ tangled.forEach(function(fn) {
+ fn.safe_ids = tw.safe_ids;
+ walk_fn_def(tw, fn);
+ });
+ fn_defs.forEach(function(fn) {
+ delete fn.safe_ids;
+ });
+ delete scope.fn_defs;
+ delete scope.may_call_this;
}
function push(tw) {
@@ -592,13 +615,13 @@ merge(Compressor.prototype, {
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolLet);
});
- if (def.fixed === null && def.safe_ids) {
+ if (def.fixed === false) return false;
+ var safe = tw.safe_ids[def.id];
+ if (def.safe_ids) {
def.safe_ids[def.id] = false;
delete def.safe_ids;
- return true;
+ return def.fixed === null || HOP(tw.safe_ids, def.id) && !safe.read;
}
- if (def.fixed === false) return false;
- var safe = tw.safe_ids[def.id];
if (!HOP(tw.safe_ids, def.id)) {
if (!safe) return false;
if (safe.read) {
@@ -813,8 +836,7 @@ merge(Compressor.prototype, {
}, visit);
walk_lambda(fn, tw);
var safe_ids = tw.safe_ids;
- pop(tw);
- walk_defuns(tw, fn);
+ pop_scope(tw, fn);
if (!aborts) tw.safe_ids = safe_ids;
return true;
@@ -835,7 +857,8 @@ merge(Compressor.prototype, {
var node = this;
var left = node.left;
var right = node.right;
- var scan = left instanceof AST_Destructured || left instanceof AST_SymbolRef;
+ var ld = left instanceof AST_SymbolRef && left.definition();
+ var scan = ld || left instanceof AST_Destructured;
switch (node.operator) {
case "=":
if (left.equivalent_to(right) && !left.has_side_effects(compressor)) {
@@ -844,7 +867,17 @@ merge(Compressor.prototype, {
node.__drop = true;
return true;
}
- if (scan) {
+ if (ld && right instanceof AST_LambdaExpression) {
+ walk_assign();
+ if (ld.escaped.length) {
+ right.walk(tw);
+ } else {
+ right.parent_scope.resolve().fn_defs.push(right);
+ right.safe_ids = null;
+ }
+ return true;
+ } else if (scan) {
+ right.walk(tw);
walk_assign();
return true;
}
@@ -856,6 +889,7 @@ merge(Compressor.prototype, {
left.walk(tw);
push(tw);
if (scan) {
+ right.walk(tw);
walk_assign();
} else {
mark_assignment_to_arguments(left);
@@ -868,20 +902,19 @@ merge(Compressor.prototype, {
mark_assignment_to_arguments(left);
return;
}
- var d = left.definition();
- d.assignments++;
- var fixed = d.fixed;
+ ld.assignments++;
+ var fixed = ld.fixed;
if (is_modified(compressor, tw, node, node, 0)) {
- d.fixed = false;
+ ld.fixed = false;
return;
}
- var safe = safe_to_read(tw, d);
+ var safe = safe_to_read(tw, ld);
right.walk(tw);
- if (safe && !left.in_arg && safe_to_assign(tw, d)) {
- push_ref(d, left);
- mark(tw, d);
- if (d.single_use) d.single_use = false;
- left.fixed = d.fixed = function() {
+ if (safe && !left.in_arg && safe_to_assign(tw, ld)) {
+ push_ref(ld, left);
+ mark(tw, ld);
+ if (ld.single_use) ld.single_use = false;
+ left.fixed = ld.fixed = function() {
return make_node(AST_Binary, node, {
operator: node.operator.slice(0, -1),
left: make_ref(left, fixed),
@@ -892,7 +925,7 @@ merge(Compressor.prototype, {
left.fixed.assigns.push(node);
} else {
left.walk(tw);
- d.fixed = false;
+ ld.fixed = false;
}
return true;
}
@@ -920,8 +953,8 @@ merge(Compressor.prototype, {
}
function walk_assign() {
- right.walk(tw);
- var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d));
+ var recursive = ld && recursive_ref(tw, ld);
+ var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive);
scan_declaration(tw, compressor, left, function() {
return node.right;
}, function(sym, fixed, walk) {
@@ -956,9 +989,7 @@ merge(Compressor.prototype, {
return true;
});
def(AST_BlockScope, function(tw, descend, compressor) {
- this.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
+ reset_block_variables(tw, compressor, this);
});
def(AST_Call, function(tw, descend) {
var node = this;
@@ -969,43 +1000,43 @@ merge(Compressor.prototype, {
arg.walk(tw);
if (arg instanceof AST_Spread) iife = false;
});
- if (iife) exp.reduce_vars = reduce_iife;
+ if (iife) {
+ exp.reduce_vars = reduce_iife;
+ } else {
+ exp.safe_ids = tw.safe_ids;
+ }
exp.walk(tw);
if (iife) delete exp.reduce_vars;
return true;
}
- var def = exp instanceof AST_SymbolRef && exp.definition();
if (node.TYPE == "Call" && tw.in_boolean_context()) {
- if (def) {
- def.bool_fn++;
+ if (exp instanceof AST_SymbolRef) {
+ exp.definition().bool_fn++;
} else if (exp instanceof AST_Assign && exp.operator == "=" && exp.left instanceof AST_SymbolRef) {
exp.left.definition().bool_fn++;
}
}
- if (def && def.fixed instanceof AST_LambdaDefinition) {
- var defun = mark_defun(tw, def);
- if (defun) {
- descend();
- defun.walk(tw);
- return true;
- }
+ exp.walk(tw);
+ var fixed = exp instanceof AST_SymbolRef && exp.fixed_value();
+ var optional = node.optional;
+ var fn;
+ if (fixed instanceof AST_Lambda) {
+ fn = mark_fn_def(tw, exp.definition(), fixed);
+ optional = false;
} else {
tw.find_parent(AST_Scope).may_call_this();
}
- if (!node.optional) return;
- exp.walk(tw);
- push(tw);
+ if (optional) push(tw);
node.args.forEach(function(arg) {
arg.walk(tw);
});
- pop(tw);
+ if (optional) pop(tw);
+ if (fn) walk_fn_def(tw, fn);
return true;
});
def(AST_Class, function(tw, descend, compressor) {
var node = this;
- node.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
+ reset_block_variables(tw, compressor, node);
if (node.extends) node.extends.walk(tw);
var props = node.properties.filter(function(prop) {
reset_flags(prop);
@@ -1057,7 +1088,7 @@ merge(Compressor.prototype, {
return true;
});
def(AST_Do, function(tw) {
- var saved_loop = tw.in_loop;
+ var save_loop = tw.in_loop;
tw.in_loop = this;
push(tw);
this.body.walk(tw);
@@ -1067,39 +1098,37 @@ merge(Compressor.prototype, {
}
this.condition.walk(tw);
pop(tw);
- tw.in_loop = saved_loop;
+ tw.in_loop = save_loop;
return true;
});
def(AST_For, function(tw, descend, compressor) {
- this.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
- if (this.init) this.init.walk(tw);
- var saved_loop = tw.in_loop;
- tw.in_loop = this;
+ var node = this;
+ reset_block_variables(tw, compressor, node);
+ if (node.init) node.init.walk(tw);
+ var save_loop = tw.in_loop;
+ tw.in_loop = node;
push(tw);
- if (this.condition) this.condition.walk(tw);
- this.body.walk(tw);
- if (this.step) {
- if (has_loop_control(this, tw.parent())) {
+ if (node.condition) node.condition.walk(tw);
+ node.body.walk(tw);
+ if (node.step) {
+ if (has_loop_control(node, tw.parent())) {
pop(tw);
push(tw);
}
- this.step.walk(tw);
+ node.step.walk(tw);
}
pop(tw);
- tw.in_loop = saved_loop;
+ tw.in_loop = save_loop;
return true;
});
def(AST_ForEnumeration, function(tw, descend, compressor) {
- this.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
- this.object.walk(tw);
- var saved_loop = tw.in_loop;
- tw.in_loop = this;
+ var node = this;
+ reset_block_variables(tw, compressor, node);
+ node.object.walk(tw);
+ var save_loop = tw.in_loop;
+ tw.in_loop = node;
push(tw);
- var init = this.init;
+ var init = node.init;
if (init instanceof AST_Definitions) {
init.definitions[0].name.mark_symbol(function(node) {
if (node instanceof AST_SymbolDeclaration) {
@@ -1120,9 +1149,9 @@ merge(Compressor.prototype, {
} else {
init.walk(tw);
}
- this.body.walk(tw);
+ node.body.walk(tw);
pop(tw);
- tw.in_loop = saved_loop;
+ tw.in_loop = save_loop;
return true;
});
def(AST_If, function(tw) {
@@ -1145,13 +1174,14 @@ merge(Compressor.prototype, {
});
def(AST_Lambda, function(tw, descend, compressor) {
var fn = this;
+ if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
+ if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
reset_variables(tw, compressor, fn);
descend();
- pop(tw);
+ pop_scope(tw, fn);
if (fn.name) mark_escaped(tw, fn.name.definition(), fn, fn.name, fn, 0, 1);
- walk_defuns(tw, fn);
return true;
});
def(AST_LambdaDefinition, function(tw, descend, compressor) {
@@ -1159,15 +1189,13 @@ merge(Compressor.prototype, {
var def = fn.name.definition();
var parent = tw.parent();
if (parent instanceof AST_ExportDeclaration || parent instanceof AST_ExportDefault) def.single_use = false;
- if (tw.defun_visited[def.id]) return true;
- if (def.init === fn && tw.defun_ids[def.id] !== tw.safe_ids) return true;
- tw.defun_visited[def.id] = true;
+ if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
+ if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
reset_variables(tw, compressor, fn);
descend();
- pop(tw);
- walk_defuns(tw, fn);
+ pop_scope(tw, fn);
return true;
});
def(AST_Sub, function(tw) {
@@ -1179,12 +1207,11 @@ merge(Compressor.prototype, {
return true;
});
def(AST_Switch, function(tw, descend, compressor) {
- this.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
- this.expression.walk(tw);
+ var node = this;
+ reset_block_variables(tw, compressor, node);
+ node.expression.walk(tw);
var first = true;
- this.body.forEach(function(branch) {
+ node.body.forEach(function(branch) {
if (branch instanceof AST_Default) return;
branch.expression.walk(tw);
if (first) {
@@ -1193,7 +1220,7 @@ merge(Compressor.prototype, {
}
})
if (!first) pop(tw);
- walk_body(this, tw);
+ walk_body(node, tw);
return true;
});
def(AST_SwitchBranch, function(tw) {
@@ -1258,36 +1285,62 @@ merge(Compressor.prototype, {
}
if (!this.fixed) this.fixed = d.fixed;
var parent;
- if (d.fixed instanceof AST_LambdaDefinition
+ if (value instanceof AST_Lambda
&& !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) {
- var defun = mark_defun(tw, d);
- if (defun) defun.walk(tw);
+ var fn = mark_fn_def(tw, d, value);
+ if (fn) walk_fn_def(tw, fn);
+ }
+ });
+ def(AST_Template, function(tw, descend) {
+ var node = this;
+ var tag = node.tag;
+ if (!tag) return;
+ if (tag instanceof AST_LambdaExpression) {
+ node.expressions.forEach(function(exp) {
+ exp.walk(tw);
+ });
+ tag.safe_ids = tw.safe_ids;
+ tag.walk(tw);
+ delete tag.reduce_vars;
+ return true;
}
+ tag.walk(tw);
+ var fixed = tag instanceof AST_SymbolRef && tag.fixed_value();
+ var fn;
+ if (fixed instanceof AST_Lambda) {
+ fn = mark_fn_def(tw, tag.definition(), fixed);
+ } else {
+ tw.find_parent(AST_Scope).may_call_this();
+ }
+ node.expressions.forEach(function(exp) {
+ exp.walk(tw);
+ });
+ if (fn) walk_fn_def(tw, fn);
+ return true;
});
def(AST_Toplevel, function(tw, descend, compressor) {
- this.globals.each(function(def) {
+ var node = this;
+ node.globals.each(function(def) {
reset_def(tw, compressor, def);
});
push(tw);
- reset_variables(tw, compressor, this);
+ reset_variables(tw, compressor, node);
descend();
- pop(tw);
- walk_defuns(tw, this);
+ pop_scope(tw, node);
return true;
});
def(AST_Try, function(tw, descend, compressor) {
- this.variables.each(function(def) {
- reset_def(tw, compressor, def);
- });
+ var node = this;
+ reset_block_variables(tw, compressor, node);
push(tw);
- walk_body(this, tw);
+ walk_body(node, tw);
pop(tw);
- if (this.bcatch) {
+ if (node.bcatch) {
push(tw);
- this.bcatch.walk(tw);
+ node.bcatch.walk(tw);
pop(tw);
}
- if (this.bfinally) this.bfinally.walk(tw);
+ if (node.bfinally) node.bfinally.walk(tw);
return true;
});
def(AST_Unary, function(tw, descend) {
@@ -1338,8 +1391,12 @@ merge(Compressor.prototype, {
});
def(AST_VarDef, function(tw, descend, compressor) {
var node = this;
- if (node.value) {
- node.value.walk(tw);
+ var value = node.value;
+ if (value instanceof AST_LambdaExpression && node.name instanceof AST_SymbolDeclaration) {
+ value.parent_scope.resolve().fn_defs.push(value);
+ value.safe_ids = null;
+ } else if (value) {
+ value.walk(tw);
} else if (!(tw.parent() instanceof AST_Let)) {
return;
}
@@ -1363,12 +1420,12 @@ merge(Compressor.prototype, {
return true;
});
def(AST_While, function(tw, descend) {
- var saved_loop = tw.in_loop;
+ var save_loop = tw.in_loop;
tw.in_loop = this;
push(tw);
descend();
pop(tw);
- tw.in_loop = saved_loop;
+ tw.in_loop = save_loop;
return true;
});
})(function(node, func) {
@@ -1387,9 +1444,9 @@ merge(Compressor.prototype, {
reset_flags(node);
return node.reduce_vars(tw, descend, compressor);
} : reset_flags);
- // Flow control for visiting `AST_Defun`s
- tw.defun_ids = Object.create(null);
- tw.defun_visited = Object.create(null);
+ // Flow control for visiting lambda definitions
+ tw.fn_scanning = null;
+ tw.fn_visited = [];
// Record the loop body in which `AST_SymbolDeclaration` is first encountered
tw.in_loop = null;
tw.loop_ids = Object.create(null);
@@ -1642,9 +1699,7 @@ merge(Compressor.prototype, {
return all(block.body, function(stat) {
return is_empty(stat)
|| stat instanceof AST_Defun
- || stat instanceof AST_Var && all(stat.definitions, function(var_def) {
- return !var_def.value;
- });
+ || stat instanceof AST_Var && declarations_only(stat);
});
}
@@ -6468,7 +6523,7 @@ merge(Compressor.prototype, {
}
} else if (compressor.option("functions")
&& !compressor.option("ie8")
- && node instanceof AST_Var
+ && drop_sym
&& var_defs[sym.id] == 1
&& sym.assignments == 0
&& value instanceof AST_LambdaExpression
@@ -6542,7 +6597,7 @@ merge(Compressor.prototype, {
}
function can_declare_defun(fn) {
- if (compressor.has_directive("use strict") || !(fn instanceof AST_Function)) {
+ if (!is_var || compressor.has_directive("use strict") || !(fn instanceof AST_Function)) {
return parent instanceof AST_Scope;
}
return parent instanceof AST_Block
@@ -9501,9 +9556,7 @@ merge(Compressor.prototype, {
for (var i = 0; i < len; i++) {
var line = fn.body[i];
if (line instanceof AST_Var) {
- var assigned = var_assigned || !all(line.definitions, function(var_def) {
- return !var_def.value;
- });
+ var assigned = var_assigned || !declarations_only(line);
if (assigned) {
var_assigned = true;
if (stat) return false;
diff --git a/test/compress/arrows.js b/test/compress/arrows.js
index be869512..abbbbf90 100644
--- a/test/compress/arrows.js
+++ b/test/compress/arrows.js
@@ -556,6 +556,38 @@ reduce_iife_3: {
node_version: ">=4"
}
+reduce_lambda: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var f = () => {
+ console.log(a, b);
+ };
+ var a = "foo", b = 42;
+ f();
+ b = "bar";
+ f();
+ }
+ expect: {
+ var f = () => {
+ console.log("foo", b);
+ };
+ var b = 42;
+ f();
+ b = "bar";
+ f();
+ }
+ expect_stdout: [
+ "foo 42",
+ "foo bar",
+ ]
+ node_version: ">=4"
+}
+
single_use_recursive: {
options = {
reduce_vars: true,
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 4c2ffece..ed821c29 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -3081,7 +3081,8 @@ issue_4235: {
}
expect: {
void function() {
- var f = console.log(f);
+ var f;
+ console.log(f);
}();
}
expect_stdout: "undefined"
diff --git a/test/compress/functions.js b/test/compress/functions.js
index e4766cd5..cad6e5e4 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -2905,6 +2905,7 @@ issue_2437: {
issue_2485_1: {
options = {
functions: true,
+ passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -2955,6 +2956,7 @@ issue_2485_2: {
options = {
functions: true,
inline: true,
+ passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
diff --git a/test/compress/hoist_vars.js b/test/compress/hoist_vars.js
index fe39cdde..97987fd9 100644
--- a/test/compress/hoist_vars.js
+++ b/test/compress/hoist_vars.js
@@ -152,7 +152,8 @@ issue_4487: {
}
expect: {
function a() {
- var f = console.log(typeof f);
+ var f;
+ console.log(typeof f);
}
a();
}
diff --git a/test/compress/let.js b/test/compress/let.js
index 0a23f65b..59e60ae0 100644
--- a/test/compress/let.js
+++ b/test/compress/let.js
@@ -494,6 +494,41 @@ reduce_vars_3: {
node_version: ">=4"
}
+reduce_lambda: {
+ options = {
+ evaluate: true,
+ functions: true,
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ "use strict";
+ let f = function() {
+ console.log(a, b);
+ };
+ let a = "foo", b = 42;
+ f();
+ b = "bar";
+ f();
+ }
+ expect: {
+ "use strict";
+ function f() {
+ console.log("foo", b);
+ }
+ let b = 42;
+ f();
+ b = "bar";
+ f();
+ }
+ expect_stdout: [
+ "foo 42",
+ "foo bar",
+ ]
+ node_version: ">=4"
+}
+
hoist_props: {
options = {
hoist_props: true,
diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js
index 935b3e31..ad2117cc 100644
--- a/test/compress/pure_getters.js
+++ b/test/compress/pure_getters.js
@@ -1320,6 +1320,7 @@ issue_2878: {
issue_3427: {
options = {
+ assignments: true,
evaluate: true,
inline: true,
pure_getters: "strict",
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 69f86523..c1531b25 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -3092,7 +3092,7 @@ accessor_1: {
a = 2;
return a;
},
- b: 1
+ b: 1,
}.b, a);
}
expect: {
@@ -3102,7 +3102,7 @@ accessor_1: {
a = 2;
return a;
},
- b: 1
+ b: 1,
}.b, a);
}
expect_stdout: "1 1"
@@ -3122,7 +3122,7 @@ accessor_2: {
var B = {
get c() {
console.log(A);
- }
+ },
};
B.c;
}
@@ -3130,7 +3130,7 @@ accessor_2: {
({
get c() {
console.log(1);
- }
+ },
}).c;
}
expect_stdout: "1"
@@ -3176,7 +3176,7 @@ obj_var_1: {
var obj = {
bar: function() {
return C + C;
- }
+ },
};
console.log(obj.bar());
}
@@ -3184,7 +3184,7 @@ obj_var_1: {
console.log({
bar: function() {
return 2;
- }
+ },
}.bar());
}
expect_stdout: "2"
@@ -3208,7 +3208,7 @@ obj_var_2: {
var obj = {
bar: function() {
return C + C;
- }
+ },
};
console.log(obj.bar());
}
@@ -4422,6 +4422,7 @@ perf_2: {
perf_3: {
options = {
+ passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -4430,10 +4431,10 @@ perf_3: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
- }
+ };
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4462,10 +4463,10 @@ perf_4: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
- }
+ };
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4474,10 +4475,10 @@ perf_4: {
expect: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
- }
+ };
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4566,9 +4567,9 @@ perf_7: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
- }
+ };
return foo(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4598,9 +4599,9 @@ perf_8: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
- }
+ };
return foo(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4611,7 +4612,7 @@ perf_8: {
return function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}(x, y, z);
- }
+ };
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
diff --git a/test/reduce.js b/test/reduce.js
index 15f869e5..398b74a5 100644
--- a/test/reduce.js
+++ b/test/reduce.js
@@ -726,7 +726,7 @@ function to_statement_init(node) {
return node instanceof U.AST_Const || node instanceof U.AST_Let ? new U.AST_BlockStatement({
body: [ node ],
start: {},
- }) : to_statement(node);;
+ }) : to_statement(node);
}
function wrap_with_console_log(node) {