enhance unused (#5511)
This commit is contained in:
@@ -6634,6 +6634,7 @@ Compressor.prototype.compress = function(node) {
|
||||
var for_ins = Object.create(null);
|
||||
var in_use = [];
|
||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||
var lambda_ids = Object.create(null);
|
||||
var value_read = Object.create(null);
|
||||
var value_modified = Object.create(null);
|
||||
var var_defs = Object.create(null);
|
||||
@@ -6669,9 +6670,13 @@ Compressor.prototype.compress = function(node) {
|
||||
in_use_ids[def.id] = true;
|
||||
in_use.push(def);
|
||||
}
|
||||
if (node.extends) node.extends.walk(tw);
|
||||
var used = tw.parent() instanceof AST_ExportDefault;
|
||||
if (used) export_defaults[def.id] = true;
|
||||
if (used) {
|
||||
export_defaults[def.id] = true;
|
||||
} else if (drop && !(def.id in lambda_ids)) {
|
||||
lambda_ids[def.id] = 1;
|
||||
}
|
||||
if (node.extends) node.extends.walk(tw);
|
||||
var values = [];
|
||||
node.properties.forEach(function(prop) {
|
||||
if (prop.key instanceof AST_Node) prop.key.walk(tw);
|
||||
@@ -6691,16 +6696,18 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
if (node instanceof AST_LambdaDefinition) {
|
||||
var def = node.name.definition();
|
||||
if ((!drop_funcs || def.exported) && !(def.id in in_use_ids)) {
|
||||
var drop = drop_funcs && !def.exported;
|
||||
if (!drop && !(def.id in in_use_ids)) {
|
||||
in_use_ids[def.id] = true;
|
||||
in_use.push(def);
|
||||
}
|
||||
initializations.add(def.id, node);
|
||||
if (tw.parent() instanceof AST_ExportDefault) {
|
||||
export_defaults[def.id] = true;
|
||||
} else {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (drop && !(def.id in lambda_ids)) lambda_ids[def.id] = 1;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Definitions) {
|
||||
node.definitions.forEach(function(defn) {
|
||||
@@ -6730,6 +6737,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
assignments.add(def.id, defn);
|
||||
}
|
||||
unmark_lambda(def);
|
||||
return true;
|
||||
}, tw);
|
||||
if (side_effects) value.walk(tw);
|
||||
@@ -6921,6 +6929,14 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_Binary && node.operator == "instanceof") {
|
||||
var sym = node.right;
|
||||
if (!(sym instanceof AST_SymbolRef)) return;
|
||||
if (sym.definition().id in in_use_ids) return;
|
||||
var lhs = node.left.drop_side_effect_free(compressor);
|
||||
var value = make_node(AST_False, node).optimize(compressor);
|
||||
return lhs ? make_sequence(node, [ lhs, value ]) : value;
|
||||
}
|
||||
if (node instanceof AST_Call) {
|
||||
calls_to_drop_args.push(node);
|
||||
node.args = node.args.map(function(arg) {
|
||||
@@ -7463,6 +7479,14 @@ Compressor.prototype.compress = function(node) {
|
||||
return nodes && nodes.indexOf(node);
|
||||
}
|
||||
|
||||
function unmark_lambda(def) {
|
||||
if (lambda_ids[def.id] > 1 && !(def.id in in_use_ids)) {
|
||||
in_use_ids[def.id] = true;
|
||||
in_use.push(def);
|
||||
}
|
||||
lambda_ids[def.id] = 0;
|
||||
}
|
||||
|
||||
function verify_safe_usage(def, read, modified) {
|
||||
if (def.id in in_use_ids) return;
|
||||
if (read && modified) {
|
||||
@@ -7514,17 +7538,18 @@ Compressor.prototype.compress = function(node) {
|
||||
var def = node.expression.definition();
|
||||
if (def.scope.resolve() === self) assignments.add(def.id, node);
|
||||
}
|
||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||
if (sym && ((node_def = sym.definition()).scope.resolve() === self
|
||||
|| self.variables.get(sym.name) === node_def)
|
||||
&& !(is_arguments(node_def) && !all(self.argnames, function(argname) {
|
||||
var props = [], sym = assign_as_unused(node, props);
|
||||
if (sym) {
|
||||
var node_def = sym.definition();
|
||||
if (node_def.scope.resolve() !== self && self.variables.get(sym.name) !== node_def) return;
|
||||
if (is_arguments(node_def) && !all(self.argnames, function(argname) {
|
||||
return !argname.match_symbol(function(node) {
|
||||
if (node instanceof AST_SymbolFunarg) {
|
||||
var def = node.definition();
|
||||
return def.references.length > def.replaced;
|
||||
}
|
||||
}, true);
|
||||
}))) {
|
||||
})) return;
|
||||
if (node.write_only === "p" && node.right.may_throw_on_access(compressor, true)) return;
|
||||
var assign = props.assign;
|
||||
if (assign) {
|
||||
@@ -7554,6 +7579,17 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
}
|
||||
if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym);
|
||||
unmark_lambda(node_def);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Binary) {
|
||||
if (node.operator != "instanceof") return;
|
||||
var sym = node.right;
|
||||
if (!(sym instanceof AST_SymbolRef)) return;
|
||||
var id = sym.definition().id;
|
||||
if (!lambda_ids[id]) return;
|
||||
node.left.walk(tw);
|
||||
lambda_ids[id]++;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_ForIn) {
|
||||
@@ -7575,7 +7611,7 @@ Compressor.prototype.compress = function(node) {
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
node_def = node.definition();
|
||||
var node_def = node.definition();
|
||||
if (!(node_def.id in in_use_ids)) {
|
||||
in_use_ids[node_def.id] = true;
|
||||
in_use.push(node_def);
|
||||
|
||||
@@ -1283,6 +1283,88 @@ instanceof_lambda: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
|
||||
@@ -671,6 +671,76 @@ iife: {
|
||||
}
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
|
||||
@@ -417,6 +417,46 @@ hoist_funs: {
|
||||
expect_exact: "export function f(){}export default async function*g(){}"
|
||||
}
|
||||
|
||||
instanceof_default_class: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instanceof_default_function: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_join_vars_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
|
||||
Reference in New Issue
Block a user