drop unused: toplevel, assign-only
- assign statement does not count towards variable usage by default - only works with assignments on the same scope level as declaration - can be disabled with `unused` set to "keep_assign" - `toplevel` to drop unused top-level variables and/or functions - `top_retain` to whitelist top-level exceptions closes #1450
This commit is contained in:
10
README.md
10
README.md
@@ -361,7 +361,15 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
||||||
statically determine the condition
|
statically determine the condition
|
||||||
|
|
||||||
- `unused` -- drop unreferenced functions and variables
|
- `unused` -- drop unreferenced functions and variables (simple direct variable
|
||||||
|
assignments do not count as references unless set to `"keep_assign"`)
|
||||||
|
|
||||||
|
- `toplevel` -- drop unreferenced functions (`"funcs"`) and/or variables (`"vars"`)
|
||||||
|
in the toplevel scope (`false` by default, `true` to drop both unreferenced
|
||||||
|
functions and variables)
|
||||||
|
|
||||||
|
- `top_retain` -- prevent specific toplevel functions and variables from `unused`
|
||||||
|
removal (can be array, comma-separated, RegExp or function. Implies `toplevel`)
|
||||||
|
|
||||||
- `hoist_funs` -- hoist function declarations
|
- `hoist_funs` -- hoist function declarations
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ function Compressor(options, false_by_default) {
|
|||||||
booleans : !false_by_default,
|
booleans : !false_by_default,
|
||||||
loops : !false_by_default,
|
loops : !false_by_default,
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
|
toplevel : !!options["top_retain"],
|
||||||
|
top_retain : null,
|
||||||
hoist_funs : !false_by_default,
|
hoist_funs : !false_by_default,
|
||||||
keep_fargs : true,
|
keep_fargs : true,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
@@ -80,6 +82,21 @@ function Compressor(options, false_by_default) {
|
|||||||
global_defs : {},
|
global_defs : {},
|
||||||
passes : 1,
|
passes : 1,
|
||||||
}, true);
|
}, true);
|
||||||
|
var top_retain = this.options["top_retain"];
|
||||||
|
if (top_retain instanceof RegExp) {
|
||||||
|
this.top_retain = function(def) {
|
||||||
|
return top_retain.test(def.name);
|
||||||
|
};
|
||||||
|
} else if (typeof top_retain === "function") {
|
||||||
|
this.top_retain = top_retain;
|
||||||
|
} else if (top_retain) {
|
||||||
|
if (typeof top_retain === "string") {
|
||||||
|
top_retain = top_retain.split(/,/);
|
||||||
|
}
|
||||||
|
this.top_retain = function(def) {
|
||||||
|
return top_retain.indexOf(def.name) >= 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
var sequences = this.options["sequences"];
|
var sequences = this.options["sequences"];
|
||||||
this.sequences_limit = sequences == 1 ? 200 : sequences | 0;
|
this.sequences_limit = sequences == 1 ? 200 : sequences | 0;
|
||||||
this.warnings_produced = {};
|
this.warnings_produced = {};
|
||||||
@@ -1409,13 +1426,27 @@ merge(Compressor.prototype, {
|
|||||||
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (compressor.has_directive("use asm")) return self;
|
if (compressor.has_directive("use asm")) return self;
|
||||||
|
var toplevel = compressor.option("toplevel");
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& !(self instanceof AST_Toplevel)
|
&& (!(self instanceof AST_Toplevel) || toplevel)
|
||||||
&& !self.uses_eval
|
&& !self.uses_eval
|
||||||
&& !self.uses_with
|
&& !self.uses_with) {
|
||||||
) {
|
var assign_as_unused = !/keep_assign/.test(compressor.option("unused"));
|
||||||
|
var drop_funcs = /funcs/.test(toplevel);
|
||||||
|
var drop_vars = /vars/.test(toplevel);
|
||||||
|
if (!(self instanceof AST_Toplevel) || toplevel == true) {
|
||||||
|
drop_funcs = drop_vars = true;
|
||||||
|
}
|
||||||
var in_use = [];
|
var in_use = [];
|
||||||
var in_use_ids = {}; // avoid expensive linear scans of in_use
|
var in_use_ids = {}; // avoid expensive linear scans of in_use
|
||||||
|
if (self instanceof AST_Toplevel && compressor.top_retain) {
|
||||||
|
self.variables.each(function(def) {
|
||||||
|
if (compressor.top_retain(def) && !(def.id in in_use_ids)) {
|
||||||
|
in_use_ids[def.id] = true;
|
||||||
|
in_use.push(def);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
var initializations = new Dictionary();
|
var initializations = new Dictionary();
|
||||||
// pass 1: find out which symbols are directly used in
|
// pass 1: find out which symbols are directly used in
|
||||||
// this scope (not in nested scopes).
|
// this scope (not in nested scopes).
|
||||||
@@ -1423,11 +1454,25 @@ merge(Compressor.prototype, {
|
|||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node !== self) {
|
if (node !== self) {
|
||||||
if (node instanceof AST_Defun) {
|
if (node instanceof AST_Defun) {
|
||||||
|
if (!drop_funcs && scope === self) {
|
||||||
|
var node_def = node.name.definition();
|
||||||
|
if (!(node_def.id in in_use_ids)) {
|
||||||
|
in_use_ids[node_def.id] = true;
|
||||||
|
in_use.push(node_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
initializations.add(node.name.name, node);
|
initializations.add(node.name.name, node);
|
||||||
return true; // don't go in nested scopes
|
return true; // don't go in nested scopes
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Definitions && scope === self) {
|
if (node instanceof AST_Definitions && scope === self) {
|
||||||
node.definitions.forEach(function(def){
|
node.definitions.forEach(function(def){
|
||||||
|
if (!drop_vars) {
|
||||||
|
var node_def = def.name.definition();
|
||||||
|
if (!(node_def.id in in_use_ids)) {
|
||||||
|
in_use_ids[node_def.id] = true;
|
||||||
|
in_use.push(node_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (def.value) {
|
if (def.value) {
|
||||||
initializations.add(def.name.name, def.value);
|
initializations.add(def.name.name, def.value);
|
||||||
if (def.value.has_side_effects(compressor)) {
|
if (def.value.has_side_effects(compressor)) {
|
||||||
@@ -1437,6 +1482,14 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (assign_as_unused
|
||||||
|
&& node instanceof AST_Assign
|
||||||
|
&& node.operator == "="
|
||||||
|
&& node.left instanceof AST_SymbolRef
|
||||||
|
&& scope === self) {
|
||||||
|
node.right.walk(tw);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var node_def = node.definition();
|
var node_def = node.definition();
|
||||||
if (!(node_def.id in in_use_ids)) {
|
if (!(node_def.id in in_use_ids)) {
|
||||||
@@ -1496,7 +1549,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Defun && node !== self) {
|
if (drop_funcs && node instanceof AST_Defun && node !== self) {
|
||||||
if (!(node.name.definition().id in in_use_ids)) {
|
if (!(node.name.definition().id in in_use_ids)) {
|
||||||
compressor.warn("Dropping unused function {name} [{file}:{line},{col}]", {
|
compressor.warn("Dropping unused function {name} [{file}:{line},{col}]", {
|
||||||
name : node.name.name,
|
name : node.name.name,
|
||||||
@@ -1508,7 +1561,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
|
if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
|
||||||
var def = node.definitions.filter(function(def){
|
var def = node.definitions.filter(function(def){
|
||||||
if (def.name.definition().id in in_use_ids) return true;
|
if (def.name.definition().id in in_use_ids) return true;
|
||||||
var w = {
|
var w = {
|
||||||
@@ -1571,6 +1624,15 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
if (drop_vars && assign_as_unused
|
||||||
|
&& node instanceof AST_Assign
|
||||||
|
&& node.operator == "="
|
||||||
|
&& node.left instanceof AST_SymbolRef) {
|
||||||
|
var def = node.left.definition();
|
||||||
|
if (!(def.id in in_use_ids) && self.variables.get(def.name) === def) {
|
||||||
|
return node.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (node instanceof AST_For) {
|
if (node instanceof AST_For) {
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
|
|
||||||
|
|||||||
@@ -338,8 +338,9 @@ collapse_vars_while: {
|
|||||||
collapse_vars_do_while: {
|
collapse_vars_do_while: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:false, loops:false, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:false, loops:false, unused:"keep_assign",
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true, cascade:true,
|
||||||
|
side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
@@ -409,6 +410,79 @@ collapse_vars_do_while: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_vars_do_while_drop_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
|
comparisons:true, evaluate:true, booleans:false, loops:false, unused:true, hoist_funs:true,
|
||||||
|
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(y) {
|
||||||
|
// The constant do-while condition `c` will be replaced.
|
||||||
|
var c = 9;
|
||||||
|
do { } while (c === 77);
|
||||||
|
}
|
||||||
|
function f2(y) {
|
||||||
|
// The non-constant do-while condition `c` will not be replaced.
|
||||||
|
var c = 5 - y;
|
||||||
|
do { } while (c);
|
||||||
|
}
|
||||||
|
function f3(y) {
|
||||||
|
// The constant `x` will be replaced in the do loop body.
|
||||||
|
function fn(n) { console.log(n); }
|
||||||
|
var a = 2, x = 7;
|
||||||
|
do {
|
||||||
|
fn(a = x);
|
||||||
|
break;
|
||||||
|
} while (y);
|
||||||
|
}
|
||||||
|
function f4(y) {
|
||||||
|
// The non-constant `a` will not be replaced in the do loop body.
|
||||||
|
var a = y / 4;
|
||||||
|
do {
|
||||||
|
return a;
|
||||||
|
} while (y);
|
||||||
|
}
|
||||||
|
function f5(y) {
|
||||||
|
function p(x) { console.log(x); }
|
||||||
|
do {
|
||||||
|
// The non-constant `a` will be replaced in p(a)
|
||||||
|
// because it is declared in same block.
|
||||||
|
var a = y - 3;
|
||||||
|
p(a);
|
||||||
|
} while (--y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(y) {
|
||||||
|
do ; while (false);
|
||||||
|
}
|
||||||
|
function f2(y) {
|
||||||
|
var c = 5 - y;
|
||||||
|
do ; while (c);
|
||||||
|
}
|
||||||
|
function f3(y) {
|
||||||
|
function fn(n) { console.log(n); }
|
||||||
|
do {
|
||||||
|
fn(7);
|
||||||
|
break;
|
||||||
|
} while (y);
|
||||||
|
}
|
||||||
|
function f4(y) {
|
||||||
|
var a = y / 4;
|
||||||
|
do
|
||||||
|
return a;
|
||||||
|
while (y);
|
||||||
|
}
|
||||||
|
function f5(y) {
|
||||||
|
function p(x) { console.log(x); }
|
||||||
|
do {
|
||||||
|
p(y - 3);
|
||||||
|
} while (--y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
collapse_vars_seq: {
|
collapse_vars_seq: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
@@ -567,8 +641,9 @@ collapse_vars_assignment: {
|
|||||||
collapse_vars_lvalues: {
|
collapse_vars_lvalues: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:"keep_assign",
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true, cascade:true,
|
||||||
|
side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f0(x) { var i = ++x; return x += i; }
|
function f0(x) { var i = ++x; return x += i; }
|
||||||
@@ -593,7 +668,38 @@ collapse_vars_lvalues: {
|
|||||||
function f7(x) { var w = e1(), v = e2(), c = v - x; return (w = x) - c; }
|
function f7(x) { var w = e1(), v = e2(), c = v - x; return (w = x) - c; }
|
||||||
function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); }
|
function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); }
|
||||||
function f9(x) { var w = e1(); return e2() - x - (w = x); }
|
function f9(x) { var w = e1(); return e2() - x - (w = x); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_lvalues_drop_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
|
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f0(x) { var i = ++x; return x += i; }
|
||||||
|
function f1(x) { var a = (x -= 3); return x += a; }
|
||||||
|
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||||
|
function f3(x) { var a = (x -= 3), b = x + a; return b; }
|
||||||
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
|
function f5(x) { var w = e1(), v = e2(), c = v = --x, b = w = x; return b - c; }
|
||||||
|
function f6(x) { var w = e1(), v = e2(), c = v = --x, b = w = x; return c - b; }
|
||||||
|
function f7(x) { var w = e1(), v = e2(), c = v - x, b = w = x; return b - c; }
|
||||||
|
function f8(x) { var w = e1(), v = e2(), b = w = x, c = v - x; return b - c; }
|
||||||
|
function f9(x) { var w = e1(), v = e2(), b = w = x, c = v - x; return c - b; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0(x) { var i = ++x; return x += i; }
|
||||||
|
function f1(x) { var a = (x -= 3); return x += a; }
|
||||||
|
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||||
|
function f3(x) { var a = (x -= 3); return x + a; }
|
||||||
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
|
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
|
||||||
|
function f6(x) { e1(), e2(); return --x - x; }
|
||||||
|
function f7(x) { var v = (e1(), e2()), c = v - x; return x - c; }
|
||||||
|
function f8(x) { var v = (e1(), e2()); return x - (v - x); }
|
||||||
|
function f9(x) { e1(); return e2() - x - x; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,3 +177,382 @@ keep_fnames: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_assign: {
|
||||||
|
options = { unused: true };
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = 1;
|
||||||
|
a = 2;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var a;
|
||||||
|
return a = 1;
|
||||||
|
}
|
||||||
|
function f5() {
|
||||||
|
var a;
|
||||||
|
return function() {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
function f5() {
|
||||||
|
var a;
|
||||||
|
return function() {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_assign: {
|
||||||
|
options = { unused: "keep_assign" };
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = 1;
|
||||||
|
a = 2;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var a;
|
||||||
|
return a = 1;
|
||||||
|
}
|
||||||
|
function f5() {
|
||||||
|
var a;
|
||||||
|
return function() {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = 1;
|
||||||
|
a = 2;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var a;
|
||||||
|
return a = 1;
|
||||||
|
}
|
||||||
|
function f5() {
|
||||||
|
var a;
|
||||||
|
return function() {
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_funcs: {
|
||||||
|
options = { toplevel: "funcs", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_vars: {
|
||||||
|
options = { toplevel: "vars", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_vars_fargs: {
|
||||||
|
options = { keep_fargs: false, toplevel: "vars", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = g;
|
||||||
|
function f() {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_all: {
|
||||||
|
options = { toplevel: true, unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
2;
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_retain: {
|
||||||
|
options = { top_retain: "f,a,o", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_retain_array: {
|
||||||
|
options = { top_retain: [ "f", "a", "o" ], unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_retain_regex: {
|
||||||
|
options = { top_retain: /^[fao]$/, unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_all_retain: {
|
||||||
|
options = { toplevel: true, top_retain: "f,a,o", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_funcs_retain: {
|
||||||
|
options = { toplevel: "funcs", top_retain: "f,a,o", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_vars_retain: {
|
||||||
|
options = { toplevel: "vars", top_retain: "f,a,o", unused: true };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_toplevel_keep_assign: {
|
||||||
|
options = { toplevel: true, unused: "keep_assign" };
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = g;
|
||||||
|
function f(d) {
|
||||||
|
return function() {
|
||||||
|
c = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = 2;
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 1;
|
||||||
|
a = 2;
|
||||||
|
console.log(b = 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user