|
|
|
|
@@ -94,7 +94,6 @@ function Compressor(options, false_by_default) {
|
|
|
|
|
unsafe_regexp : false,
|
|
|
|
|
unsafe_undefined: false,
|
|
|
|
|
unused : !false_by_default,
|
|
|
|
|
warnings : false,
|
|
|
|
|
}, true);
|
|
|
|
|
var global_defs = this.options["global_defs"];
|
|
|
|
|
if (typeof global_defs == "object") for (var key in global_defs) {
|
|
|
|
|
@@ -144,7 +143,6 @@ function Compressor(options, false_by_default) {
|
|
|
|
|
};
|
|
|
|
|
var sequences = this.options["sequences"];
|
|
|
|
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
|
|
|
|
this.warnings_produced = {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Compressor.prototype = new TreeTransformer;
|
|
|
|
|
@@ -175,7 +173,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
node.walk(new TreeWalker(function() {
|
|
|
|
|
count++;
|
|
|
|
|
}));
|
|
|
|
|
this.info("pass " + pass + ": last_count: " + min_count + ", count: " + count);
|
|
|
|
|
AST_Node.info("pass " + pass + ": last_count: " + min_count + ", count: " + count);
|
|
|
|
|
if (count < min_count) {
|
|
|
|
|
min_count = count;
|
|
|
|
|
stopping = false;
|
|
|
|
|
@@ -191,24 +189,6 @@ merge(Compressor.prototype, {
|
|
|
|
|
}
|
|
|
|
|
return node;
|
|
|
|
|
},
|
|
|
|
|
info: function() {
|
|
|
|
|
if (this.options.warnings == "verbose") {
|
|
|
|
|
AST_Node.warn.apply(AST_Node, arguments);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
warn: function(text, props) {
|
|
|
|
|
if (this.options.warnings) {
|
|
|
|
|
// only emit unique warnings
|
|
|
|
|
var message = string_template(text, props);
|
|
|
|
|
if (!(message in this.warnings_produced)) {
|
|
|
|
|
this.warnings_produced[message] = true;
|
|
|
|
|
AST_Node.warn.apply(AST_Node, arguments);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
clear_warnings: function() {
|
|
|
|
|
this.warnings_produced = {};
|
|
|
|
|
},
|
|
|
|
|
before: function(node, descend, in_list) {
|
|
|
|
|
if (node._squeezed) return node;
|
|
|
|
|
var is_scope = node instanceof AST_Scope;
|
|
|
|
|
@@ -1138,7 +1118,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
if (value_def && candidate instanceof AST_VarDef) return node;
|
|
|
|
|
}
|
|
|
|
|
CHANGED = abort = true;
|
|
|
|
|
compressor.info("Collapsing {name} [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.info("Collapsing {name} [{file}:{line},{col}]", {
|
|
|
|
|
name: node.print_to_string(),
|
|
|
|
|
file: node.start.file,
|
|
|
|
|
line: node.start.line,
|
|
|
|
|
@@ -1963,7 +1943,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
statements.length = n;
|
|
|
|
|
CHANGED = n != len;
|
|
|
|
|
if (has_quit) has_quit.forEach(function(stat) {
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, stat, statements);
|
|
|
|
|
extract_declarations_from_unreachable_code(stat, statements);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2216,13 +2196,13 @@ merge(Compressor.prototype, {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function extract_declarations_from_unreachable_code(compressor, stat, target) {
|
|
|
|
|
function extract_declarations_from_unreachable_code(stat, target) {
|
|
|
|
|
if (!(stat instanceof AST_Defun)) {
|
|
|
|
|
compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start);
|
|
|
|
|
AST_Node.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start);
|
|
|
|
|
}
|
|
|
|
|
stat.walk(new TreeWalker(function(node) {
|
|
|
|
|
if (node instanceof AST_Definitions) {
|
|
|
|
|
compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start);
|
|
|
|
|
AST_Node.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start);
|
|
|
|
|
node.remove_initializers();
|
|
|
|
|
target.push(node);
|
|
|
|
|
return true;
|
|
|
|
|
@@ -2599,8 +2579,8 @@ merge(Compressor.prototype, {
|
|
|
|
|
return make_node_from_constant(value, orig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function warn(compressor, node) {
|
|
|
|
|
compressor.warn("global_defs " + node.print_to_string() + " redefined [{file}:{line},{col}]", node.start);
|
|
|
|
|
function warn(node) {
|
|
|
|
|
AST_Node.warn("global_defs " + node.print_to_string() + " redefined [{file}:{line},{col}]", node.start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
|
|
|
|
|
@@ -2616,7 +2596,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
child = parent;
|
|
|
|
|
}
|
|
|
|
|
if (is_lhs(child, parent)) {
|
|
|
|
|
warn(compressor, node);
|
|
|
|
|
warn(node);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return def;
|
|
|
|
|
@@ -2628,7 +2608,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
});
|
|
|
|
|
def(AST_SymbolDeclaration, function(compressor) {
|
|
|
|
|
if (!this.global()) return;
|
|
|
|
|
if (HOP(compressor.option("global_defs"), this.name)) warn(compressor, this);
|
|
|
|
|
if (HOP(compressor.option("global_defs"), this.name)) warn(this);
|
|
|
|
|
});
|
|
|
|
|
def(AST_SymbolRef, function(compressor, suffix) {
|
|
|
|
|
if (!this.global()) return;
|
|
|
|
|
@@ -3037,7 +3017,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
try {
|
|
|
|
|
return val[key].apply(val, args);
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
compressor.warn("Error evaluating {code} [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.warn("Error evaluating {code} [{file}:{line},{col}]", {
|
|
|
|
|
code: this.print_to_string(),
|
|
|
|
|
file: this.start.file,
|
|
|
|
|
line: this.start.line,
|
|
|
|
|
@@ -3648,7 +3628,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
sym.__unused = true;
|
|
|
|
|
if (trim) {
|
|
|
|
|
a.pop();
|
|
|
|
|
compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
|
|
|
|
|
AST_Node[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
trim = false;
|
|
|
|
|
@@ -3658,7 +3638,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
if (drop_funcs && node instanceof AST_Defun && node !== self) {
|
|
|
|
|
var def = node.name.definition();
|
|
|
|
|
if (!(def.id in in_use_ids)) {
|
|
|
|
|
compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
|
|
|
|
|
AST_Node[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
|
|
|
|
|
def.eliminated++;
|
|
|
|
|
return make_node(AST_EmptyStatement, node);
|
|
|
|
|
}
|
|
|
|
|
@@ -3679,7 +3659,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
}
|
|
|
|
|
var var_defs = var_defs_by_id.get(sym.id);
|
|
|
|
|
if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
|
|
|
|
|
compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
AST_Node.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
if (def.value) {
|
|
|
|
|
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
|
|
|
|
sym.references.push(ref);
|
|
|
|
|
@@ -3704,7 +3684,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
&& def.value instanceof AST_Function
|
|
|
|
|
&& can_rename(def.value, def.name.name)
|
|
|
|
|
&& (!compressor.has_directive("use strict") || parent instanceof AST_Scope)) {
|
|
|
|
|
compressor.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
AST_Node.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
var defun = make_node(AST_Defun, def, def.value);
|
|
|
|
|
defun.name = make_node(AST_SymbolDefun, def.name, def.name);
|
|
|
|
|
var name_def = def.name.scope.resolve().def_function(defun.name);
|
|
|
|
|
@@ -3741,10 +3721,10 @@ merge(Compressor.prototype, {
|
|
|
|
|
} else {
|
|
|
|
|
var value = def.value && def.value.drop_side_effect_free(compressor);
|
|
|
|
|
if (value) {
|
|
|
|
|
compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
AST_Node.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
side_effects.push(value);
|
|
|
|
|
} else {
|
|
|
|
|
compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
AST_Node[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", template(def.name));
|
|
|
|
|
}
|
|
|
|
|
sym.eliminated++;
|
|
|
|
|
}
|
|
|
|
|
@@ -4209,9 +4189,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
if (this.pure) {
|
|
|
|
|
compressor.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
|
|
|
|
|
}
|
|
|
|
|
if (this.pure) AST_Node.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
|
|
|
|
|
var args = trim(this.args, compressor, first_in_statement);
|
|
|
|
|
return args && make_sequence(this, args);
|
|
|
|
|
});
|
|
|
|
|
@@ -4294,7 +4272,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
var body = self.body;
|
|
|
|
|
var node = body.drop_side_effect_free(compressor, true);
|
|
|
|
|
if (!node) {
|
|
|
|
|
compressor.warn("Dropping side-effect-free statement [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Dropping side-effect-free statement [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_node(AST_EmptyStatement, self);
|
|
|
|
|
}
|
|
|
|
|
if (node !== body) {
|
|
|
|
|
@@ -4373,7 +4351,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
body: self.condition
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
|
|
|
|
extract_declarations_from_unreachable_code(self.body, body);
|
|
|
|
|
return make_node(AST_BlockStatement, self, {
|
|
|
|
|
body: body
|
|
|
|
|
});
|
|
|
|
|
@@ -4446,7 +4424,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
if (!cond) {
|
|
|
|
|
if (compressor.option("dead_code")) {
|
|
|
|
|
var body = [];
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
|
|
|
|
extract_declarations_from_unreachable_code(self.body, body);
|
|
|
|
|
if (self.init instanceof AST_Statement) {
|
|
|
|
|
body.push(self.init);
|
|
|
|
|
} else if (self.init) {
|
|
|
|
|
@@ -4493,20 +4471,18 @@ merge(Compressor.prototype, {
|
|
|
|
|
cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
|
|
|
|
}
|
|
|
|
|
if (!cond) {
|
|
|
|
|
compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
|
|
|
|
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
|
|
|
|
var body = [];
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, self.body, body);
|
|
|
|
|
extract_declarations_from_unreachable_code(self.body, body);
|
|
|
|
|
body.push(make_node(AST_SimpleStatement, self.condition, {
|
|
|
|
|
body: self.condition
|
|
|
|
|
}));
|
|
|
|
|
if (self.alternative) body.push(self.alternative);
|
|
|
|
|
return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
|
|
|
|
|
} else if (!(cond instanceof AST_Node)) {
|
|
|
|
|
compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
|
|
|
|
|
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
|
|
|
|
|
var body = [];
|
|
|
|
|
if (self.alternative) {
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, self.alternative, body);
|
|
|
|
|
}
|
|
|
|
|
if (self.alternative) extract_declarations_from_unreachable_code(self.alternative, body);
|
|
|
|
|
body.push(make_node(AST_SimpleStatement, self.condition, {
|
|
|
|
|
body: self.condition
|
|
|
|
|
}));
|
|
|
|
|
@@ -4721,7 +4697,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
if (prev && !aborts(prev)) {
|
|
|
|
|
prev.body = prev.body.concat(branch.body);
|
|
|
|
|
} else {
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, branch, decl);
|
|
|
|
|
extract_declarations_from_unreachable_code(branch, decl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
@@ -4732,7 +4708,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
if (compressor.option("dead_code") && all(self.body, is_empty)) {
|
|
|
|
|
var body = [];
|
|
|
|
|
if (self.bcatch) {
|
|
|
|
|
extract_declarations_from_unreachable_code(compressor, self.bcatch, body);
|
|
|
|
|
extract_declarations_from_unreachable_code(self.bcatch, body);
|
|
|
|
|
body.forEach(function(stat) {
|
|
|
|
|
if (!(stat instanceof AST_Definitions)) return;
|
|
|
|
|
stat.definitions.forEach(function(var_def) {
|
|
|
|
|
@@ -4844,7 +4820,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
elements: elements
|
|
|
|
|
});
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
compressor.warn("Invalid array length: {length} [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.warn("Invalid array length: {length} [{file}:{line},{col}]", {
|
|
|
|
|
length: length,
|
|
|
|
|
file: self.start.file,
|
|
|
|
|
line: self.start.line,
|
|
|
|
|
@@ -4904,7 +4880,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
value: RegExp.apply(RegExp, params),
|
|
|
|
|
}));
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
compressor.warn("Error converting {expr} [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.warn("Error converting {expr} [{file}:{line},{col}]", {
|
|
|
|
|
expr: self.print_to_string(),
|
|
|
|
|
file: self.start.file,
|
|
|
|
|
line: self.start.line,
|
|
|
|
|
@@ -5087,8 +5063,8 @@ merge(Compressor.prototype, {
|
|
|
|
|
return self;
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
if (ex instanceof JS_Parse_Error) {
|
|
|
|
|
compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start);
|
|
|
|
|
compressor.warn(ex.toString());
|
|
|
|
|
AST_Node.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start);
|
|
|
|
|
AST_Node.warn(ex.toString());
|
|
|
|
|
} else {
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
@@ -5458,7 +5434,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
case "typeof":
|
|
|
|
|
// typeof always returns a non-empty string, thus it's
|
|
|
|
|
// always true in booleans
|
|
|
|
|
compressor.warn("Boolean expression always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Boolean expression always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [
|
|
|
|
|
e,
|
|
|
|
|
make_node(AST_True, self)
|
|
|
|
|
@@ -5567,7 +5543,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
case "===":
|
|
|
|
|
case "!==":
|
|
|
|
|
if (is_undefined(self.left, compressor) && self.right.is_defined(compressor)) {
|
|
|
|
|
compressor.warn("Expression always defined [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Expression always defined [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [
|
|
|
|
|
self.right,
|
|
|
|
|
make_node(self.operator == "===" ? AST_False : AST_True, self)
|
|
|
|
|
@@ -5646,14 +5622,14 @@ merge(Compressor.prototype, {
|
|
|
|
|
var ll = self.left.evaluate(compressor);
|
|
|
|
|
var rr = self.right.evaluate(compressor);
|
|
|
|
|
if (ll && typeof ll == "string") {
|
|
|
|
|
compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [
|
|
|
|
|
self.right,
|
|
|
|
|
make_node(AST_True, self)
|
|
|
|
|
]).optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
if (rr && typeof rr == "string") {
|
|
|
|
|
compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [
|
|
|
|
|
self.left,
|
|
|
|
|
make_node(AST_True, self)
|
|
|
|
|
@@ -5713,16 +5689,16 @@ merge(Compressor.prototype, {
|
|
|
|
|
case "&&":
|
|
|
|
|
var ll = fuzzy_eval(self.left);
|
|
|
|
|
if (!ll) {
|
|
|
|
|
compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
return maintain_this_binding(compressor, compressor.parent(), compressor.self(), self.left).optimize(compressor);
|
|
|
|
|
} else if (!(ll instanceof AST_Node)) {
|
|
|
|
|
compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
var rr = self.right.evaluate(compressor);
|
|
|
|
|
if (!rr) {
|
|
|
|
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
|
|
|
|
compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Boolean && always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [
|
|
|
|
|
self.left,
|
|
|
|
|
make_node(AST_False, self)
|
|
|
|
|
@@ -5732,7 +5708,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
var parent = compressor.parent();
|
|
|
|
|
if (parent.operator == "&&" && parent.left === compressor.self()
|
|
|
|
|
|| compressor.option("booleans") && compressor.in_boolean_context()) {
|
|
|
|
|
compressor.warn("Dropping side-effect-free && [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Dropping side-effect-free && [{file}:{line},{col}]", self.start);
|
|
|
|
|
return self.left.optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -5749,10 +5725,10 @@ merge(Compressor.prototype, {
|
|
|
|
|
case "||":
|
|
|
|
|
var ll = fuzzy_eval(self.left);
|
|
|
|
|
if (!ll) {
|
|
|
|
|
compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
|
|
|
|
|
} else if (!(ll instanceof AST_Node)) {
|
|
|
|
|
compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return maintain_this_binding(compressor, compressor.parent(), compressor.self(), self.left).optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
var rr = self.right.evaluate(compressor);
|
|
|
|
|
@@ -5760,12 +5736,12 @@ merge(Compressor.prototype, {
|
|
|
|
|
var parent = compressor.parent();
|
|
|
|
|
if (parent.operator == "||" && parent.left === compressor.self()
|
|
|
|
|
|| compressor.option("booleans") && compressor.in_boolean_context()) {
|
|
|
|
|
compressor.warn("Dropping side-effect-free || [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Dropping side-effect-free || [{file}:{line},{col}]", self.start);
|
|
|
|
|
return self.left.optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
} else if (!(rr instanceof AST_Node)) {
|
|
|
|
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
|
|
|
|
compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [
|
|
|
|
|
self.left,
|
|
|
|
|
make_node(AST_True, self)
|
|
|
|
|
@@ -6355,10 +6331,10 @@ merge(Compressor.prototype, {
|
|
|
|
|
}
|
|
|
|
|
var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
|
|
|
|
if (!cond) {
|
|
|
|
|
compressor.warn("Condition always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [ self.condition, self.alternative ]).optimize(compressor);
|
|
|
|
|
} else if (!(cond instanceof AST_Node)) {
|
|
|
|
|
compressor.warn("Condition always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.start);
|
|
|
|
|
return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor);
|
|
|
|
|
}
|
|
|
|
|
var negated = cond.negate(compressor, first_in_statement(compressor));
|
|
|
|
|
@@ -6597,7 +6573,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
});
|
|
|
|
|
var p = compressor.parent();
|
|
|
|
|
if (p instanceof AST_Binary && (p.operator == "==" || p.operator == "!=")) {
|
|
|
|
|
compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", {
|
|
|
|
|
operator : p.operator,
|
|
|
|
|
value : self.value,
|
|
|
|
|
file : p.start.file,
|
|
|
|
|
@@ -6780,7 +6756,7 @@ merge(Compressor.prototype, {
|
|
|
|
|
|
|
|
|
|
OPT(AST_Dot, function(self, compressor) {
|
|
|
|
|
if (self.property == "arguments" || self.property == "caller") {
|
|
|
|
|
compressor.warn("Function.prototype.{prop} not supported [{file}:{line},{col}]", {
|
|
|
|
|
AST_Node.warn("Function.prototype.{prop} not supported [{file}:{line},{col}]", {
|
|
|
|
|
prop: self.property,
|
|
|
|
|
file: self.start.file,
|
|
|
|
|
line: self.start.line,
|
|
|
|
|
|