unify logging functionality (#3392)

fixes #3253
fixes #3254
This commit is contained in:
Alex Lam S.L 2019-04-30 06:32:24 +08:00 committed by GitHub
parent fba008e298
commit 2ea96549c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 157 additions and 192 deletions

View File

@ -63,7 +63,7 @@ if (program.configFile) {
} }
} }
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
fatal("ERROR: cannot write source map to STDOUT"); fatal("cannot write source map to STDOUT");
} }
[ [
"compress", "compress",
@ -78,6 +78,15 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
options[name] = program[name]; options[name] = program[name];
} }
}); });
if (program.verbose) {
options.warnings = "verbose";
} else if (program.warn) {
options.warnings = true;
}
if (options.warnings) {
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
delete options.warnings;
}
if (program.beautify) { if (program.beautify) {
options.output = typeof program.beautify == "object" ? program.beautify : {}; options.output = typeof program.beautify == "object" ? program.beautify : {};
if (!("beautify" in options.output)) { if (!("beautify" in options.output)) {
@ -124,7 +133,7 @@ if (program.parse) {
if (!program.parse.acorn && !program.parse.spidermonkey) { if (!program.parse.acorn && !program.parse.spidermonkey) {
options.parse = program.parse; options.parse = program.parse;
} else if (program.sourceMap && program.sourceMap.content == "inline") { } else if (program.sourceMap && program.sourceMap.content == "inline") {
fatal("ERROR: inline source map only works with built-in parser"); fatal("inline source map only works with built-in parser");
} }
} }
if (~program.rawArgs.indexOf("--rename")) { if (~program.rawArgs.indexOf("--rename")) {
@ -144,15 +153,8 @@ if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
}; };
}(); }();
} }
if (program.verbose) {
options.warnings = "verbose";
} else if (program.warn) {
options.warnings = true;
}
if (program.self) { if (program.self) {
if (program.args.length) { if (program.args.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
print_error("WARN: Ignoring input files since --self was passed");
}
if (!options.wrap) options.wrap = "UglifyJS"; if (!options.wrap) options.wrap = "UglifyJS";
simple_glob(UglifyJS.FILES).forEach(function(name) { simple_glob(UglifyJS.FILES).forEach(function(name) {
files[convert_path(name)] = read_file(name); files[convert_path(name)] = read_file(name);
@ -180,12 +182,9 @@ function convert_ast(fn) {
} }
function run() { function run() {
UglifyJS.AST_Node.warn_function = function(msg) {
print_error("WARN: " + msg);
};
var content = program.sourceMap && program.sourceMap.content; var content = program.sourceMap && program.sourceMap.content;
if (content && content != "inline") { if (content && content != "inline") {
print_error("INFO: Using input source map: " + content); UglifyJS.AST_Node.info("Using input source map: " + content);
options.sourceMap.content = read_file(content, content); options.sourceMap.content = read_file(content, content);
} }
if (program.timings) options.timings = true; if (program.timings) options.timings = true;
@ -293,7 +292,11 @@ function run() {
} }
function fatal(message) { function fatal(message) {
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:") if (message instanceof Error) {
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
} else {
message = "ERROR: " + message;
}
print_error(message); print_error(message);
process.exit(1); process.exit(1);
} }
@ -370,9 +373,9 @@ function parse_js(flag) {
}); });
} }
})); }));
} catch(ex) { } catch (ex) {
if (flag) { if (flag) {
fatal("Error parsing arguments for '" + flag + "': " + value); fatal("cannot parse arguments for '" + flag + "': " + value);
} else { } else {
options[value] = null; options[value] = null;
} }

View File

@ -118,9 +118,25 @@ var AST_Node = DEFNODE("Node", "start end", {
} }
}, null); }, null);
AST_Node.warn = function(txt, props) { (AST_Node.log_function = function(fn, verbose) {
if (AST_Node.warn_function) AST_Node.warn_function(string_template(txt, props)); var printed = Object.create(null);
}; if (fn) {
AST_Node.info = verbose ? function(text, props) {
log("INFO: " + string_template(text, props));
} : noop;
AST_Node.warn = function(text, props) {
log("WARN: " + string_template(text, props));
};
} else {
AST_Node.info = AST_Node.warn = noop;
}
function log(msg) {
if (printed[msg]) return;
printed[msg] = true;
fn(msg);
}
})();
/* -----[ statements ]----- */ /* -----[ statements ]----- */

View File

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

View File

@ -51,7 +51,6 @@ function to_json(cache) {
} }
function minify(files, options) { function minify(files, options) {
var warn_function = AST_Node.warn_function;
try { try {
options = defaults(options, { options = defaults(options, {
compress: {}, compress: {},
@ -78,7 +77,6 @@ function minify(files, options) {
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]); set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]); set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
set_shorthand("toplevel", options, [ "compress", "mangle" ]); set_shorthand("toplevel", options, [ "compress", "mangle" ]);
set_shorthand("warnings", options, [ "compress" ]);
var quoted_props; var quoted_props;
if (options.mangle) { if (options.mangle) {
options.mangle = defaults(options.mangle, { options.mangle = defaults(options.mangle, {
@ -116,11 +114,9 @@ function minify(files, options) {
}, true); }, true);
} }
var warnings = []; var warnings = [];
if (options.warnings && !AST_Node.warn_function) { if (options.warnings) AST_Node.log_function(function(warning) {
AST_Node.warn_function = function(warning) {
warnings.push(warning); warnings.push(warning);
}; }, options.warnings == "verbose");
}
if (timings) timings.parse = Date.now(); if (timings) timings.parse = Date.now();
var source_maps, toplevel; var source_maps, toplevel;
if (files instanceof AST_Toplevel) { if (files instanceof AST_Toplevel) {
@ -240,7 +236,5 @@ function minify(files, options) {
return result; return result;
} catch (ex) { } catch (ex) {
return { error: ex }; return { error: ex };
} finally {
AST_Node.warn_function = warn_function;
} }
} }

View File

@ -504,7 +504,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
var regexp = new RegExp(source, mods); var regexp = new RegExp(source, mods);
regexp.raw_source = source; regexp.raw_source = source;
return token("regexp", regexp); return token("regexp", regexp);
} catch(e) { } catch (e) {
parse_error(e.message); parse_error(e.message);
} }
}); });
@ -556,7 +556,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
return function(x) { return function(x) {
try { try {
return cont(x); return cont(x);
} catch(ex) { } catch (ex) {
if (ex === EX_EOF) parse_error(eof_error); if (ex === EX_EOF) parse_error(eof_error);
else throw ex; else throw ex;
} }

View File

@ -70,7 +70,7 @@ function configure_error_stack(fn) {
err.name = this.name; err.name = this.name;
try { try {
throw err; throw err;
} catch(e) { } catch (e) {
return e.stack; return e.stack;
} }
} }

View File

@ -4194,7 +4194,7 @@ may_throw_2: {
var a = x(); var a = x();
++b; ++b;
return b(a); return b(a);
} catch(e) {} } catch (e) {}
console.log(b); console.log(b);
} }
f(0); f(0);
@ -4204,7 +4204,7 @@ may_throw_2: {
try { try {
var a = x(); var a = x();
return (++b)(a); return (++b)(a);
} catch(e) {} } catch (e) {}
console.log(b); console.log(b);
} }
f(0); f(0);

View File

@ -144,7 +144,7 @@ unused_var_in_catch: {
function foo() { function foo() {
try { try {
foo(); foo();
} catch(ex) { } catch (ex) {
var x = 10; var x = 10;
} }
} }
@ -153,7 +153,7 @@ unused_var_in_catch: {
function foo() { function foo() {
try { try {
foo(); foo();
} catch(ex) {} } catch (ex) {}
} }
} }
} }
@ -166,7 +166,7 @@ used_var_in_catch: {
function foo() { function foo() {
try { try {
foo(); foo();
} catch(ex) { } catch (ex) {
var x = 10; var x = 10;
} }
return x; return x;
@ -176,7 +176,7 @@ used_var_in_catch: {
function foo() { function foo() {
try { try {
foo(); foo();
} catch(ex) { } catch (ex) {
var x = 10; var x = 10;
} }
return x; return x;
@ -1156,7 +1156,7 @@ var_catch_toplevel: {
try { try {
a++; a++;
x(); x();
} catch(a) { } catch (a) {
if (a) var a; if (a) var a;
var a = 10; var a = 10;
} }
@ -1167,7 +1167,7 @@ var_catch_toplevel: {
!function() { !function() {
try { try {
x(); x();
} catch(a) { } catch (a) {
var a; var a;
} }
}(); }();

View File

@ -59,9 +59,9 @@ do_screw_try_catch: {
input: { input: {
good = function(e){ good = function(e){
return function(error){ return function(error){
try{ try {
e() e()
} catch(e) { } catch (e) {
error(e) error(e)
} }
} }
@ -70,9 +70,9 @@ do_screw_try_catch: {
expect: { expect: {
good = function(n){ good = function(n){
return function(t){ return function(t){
try{ try {
n() n()
} catch(n) { } catch (n) {
t(n) t(n)
} }
} }
@ -93,9 +93,9 @@ dont_screw_try_catch: {
input: { input: {
bad = function(e){ bad = function(e){
return function(error){ return function(error){
try{ try {
e() e()
} catch(e) { } catch (e) {
error(e) error(e)
} }
} }
@ -104,9 +104,9 @@ dont_screw_try_catch: {
expect: { expect: {
bad = function(t){ bad = function(t){
return function(n){ return function(n){
try{ try {
t() t()
} catch(t) { } catch (t) {
n(t) n(t)
} }
} }
@ -137,7 +137,7 @@ do_screw_try_catch_undefined: {
} }
expect: { expect: {
function a(o){ function a(o){
try{ try {
throw "Stuff" throw "Stuff"
} catch (o) { } catch (o) {
console.log("caught: "+o) console.log("caught: "+o)
@ -172,7 +172,7 @@ dont_screw_try_catch_undefined: {
} }
expect: { expect: {
function a(n){ function a(n){
try{ try {
throw "Stuff" throw "Stuff"
} catch (undefined) { } catch (undefined) {
console.log("caught: " + undefined) console.log("caught: " + undefined)

View File

@ -59,7 +59,6 @@ non_hoisted_function_after_return_2a: {
passes: 2, passes: 2,
side_effects: true, side_effects: true,
unused: true, unused: true,
warnings: "verbose",
} }
input: { input: {
function foo(x) { function foo(x) {
@ -91,13 +90,13 @@ non_hoisted_function_after_return_2a: {
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]", "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]", "WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]", "WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
"WARN: pass 0: last_count: Infinity, count: 37", "INFO: pass 0: last_count: Infinity, count: 37",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]", "WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]", "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]", "WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:7,20]", "INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:9,16]", "INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
"WARN: pass 1: last_count: 37, count: 18", "INFO: pass 1: last_count: 37, count: 18",
] ]
} }
@ -213,7 +212,6 @@ non_hoisted_function_after_return_2a_strict: {
passes: 2, passes: 2,
side_effects: true, side_effects: true,
unused: true, unused: true,
warnings: "verbose",
} }
input: { input: {
"use strict"; "use strict";
@ -250,13 +248,13 @@ non_hoisted_function_after_return_2a_strict: {
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]", "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]", "WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]", "WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
"WARN: pass 0: last_count: Infinity, count: 48", "INFO: pass 0: last_count: Infinity, count: 48",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]", "WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]", "WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]", "WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:8,20]", "INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:10,16]", "INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
"WARN: pass 1: last_count: 48, count: 29", "INFO: pass 1: last_count: 48, count: 29",
] ]
} }

View File

@ -47,7 +47,7 @@ describe("bin/uglifyjs", function() {
}); });
}); });
it("Should give sensible error against invalid input source map", function(done) { it("Should give sensible error against invalid input source map", function(done) {
var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline"; var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline --verbose";
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
assert.ok(err); assert.ok(err);
assert.deepEqual(stderr.split(/\n/).slice(0, 2), [ assert.deepEqual(stderr.split(/\n/).slice(0, 2), [
@ -83,6 +83,7 @@ describe("bin/uglifyjs", function() {
"test/input/issue-2082/sample.js", "test/input/issue-2082/sample.js",
"--source-map", "content=test/input/issue-2082/sample.js.map", "--source-map", "content=test/input/issue-2082/sample.js.map",
"--source-map", "url=inline", "--source-map", "url=inline",
"--verbose",
].join(" "); ].join(" ");
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
if (err) throw err; if (err) throw err;
@ -202,7 +203,7 @@ describe("bin/uglifyjs", function() {
}); });
}); });
it("Should warn for missing inline source map", function(done) { it("Should warn for missing inline source map", function(done) {
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline"; var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline --warn";
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
if (err) throw err; if (err) throw err;
assert.strictEqual(stdout, [ assert.strictEqual(stdout, [
@ -221,6 +222,7 @@ describe("bin/uglifyjs", function() {
"test/input/issue-520/input.js", "test/input/issue-520/input.js",
"test/input/issue-1323/sample.js", "test/input/issue-1323/sample.js",
"--source-map", "content=inline,url=inline", "--source-map", "content=inline,url=inline",
"--warn",
].join(" "); ].join(" ");
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
if (err) throw err; if (err) throw err;
@ -466,7 +468,7 @@ describe("bin/uglifyjs", function() {
done(); done();
}); });
}); });
it("Should throw syntax error (catch(eval))", function(done) { it("Should throw syntax error (catch (eval))", function(done) {
var command = uglifyjscmd + ' test/input/invalid/try.js'; var command = uglifyjscmd + ' test/input/invalid/try.js';
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
assert.ok(err); assert.ok(err);
@ -647,7 +649,7 @@ describe("bin/uglifyjs", function() {
exec(command, function(err, stdout, stderr) { exec(command, function(err, stdout, stderr) {
assert.ok(err); assert.ok(err);
assert.strictEqual(stdout, ""); assert.strictEqual(stdout, "");
assert.strictEqual(stderr, "Error parsing arguments for 'define': a-b\n"); assert.strictEqual(stderr, "ERROR: cannot parse arguments for 'define': a-b\n");
done(); done();
}); });
}); });

View File

@ -118,32 +118,17 @@ describe("sourcemaps", function() {
assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-520/output.js", "utf8")); assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-520/output.js", "utf8"));
}); });
it("Should warn for missing inline source map", function() { it("Should warn for missing inline source map", function() {
var warn_function = UglifyJS.AST_Node.warn_function;
var warnings = [];
UglifyJS.AST_Node.warn_function = function(txt) {
warnings.push(txt);
};
try {
var result = UglifyJS.minify(read("./test/input/issue-1323/sample.js"), { var result = UglifyJS.minify(read("./test/input/issue-1323/sample.js"), {
mangle: false, mangle: false,
sourceMap: { sourceMap: {
content: "inline" content: "inline"
} },
warnings: true,
}); });
assert.strictEqual(result.code, "var bar=function(bar){return bar};"); assert.strictEqual(result.code, "var bar=function(bar){return bar};");
assert.strictEqual(warnings.length, 1); assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 0" ]);
assert.strictEqual(warnings[0], "inline source map not found: 0");
} finally {
UglifyJS.AST_Node.warn_function = warn_function;
}
}); });
it("Should handle multiple input and inline source map", function() { it("Should handle multiple input and inline source map", function() {
var warn_function = UglifyJS.AST_Node.warn_function;
var warnings = [];
UglifyJS.AST_Node.warn_function = function(txt) {
warnings.push(txt);
};
try {
var result = UglifyJS.minify([ var result = UglifyJS.minify([
read("./test/input/issue-520/input.js"), read("./test/input/issue-520/input.js"),
read("./test/input/issue-1323/sample.js"), read("./test/input/issue-1323/sample.js"),
@ -151,18 +136,15 @@ describe("sourcemaps", function() {
sourceMap: { sourceMap: {
content: "inline", content: "inline",
url: "inline", url: "inline",
} },
warnings: true,
}); });
if (result.error) throw result.error; if (result.error) throw result.error;
assert.strictEqual(result.code, [ assert.strictEqual(result.code, [
"var Foo=function(){console.log(3)};new Foo;var bar=function(o){return o};", "var Foo=function(){console.log(3)};new Foo;var bar=function(o){return o};",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElBQVMsSUFBSUYsSUNBbkQsSUFBSUcsSUFDQSxTQUFjQSxHQUNWLE9BQU9BIn0=", "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElBQVMsSUFBSUYsSUNBbkQsSUFBSUcsSUFDQSxTQUFjQSxHQUNWLE9BQU9BIn0=",
].join("\n")); ].join("\n"));
assert.strictEqual(warnings.length, 1); assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
assert.strictEqual(warnings[0], "inline source map not found: 1");
} finally {
UglifyJS.AST_Node.warn_function = warn_function;
}
}); });
it("Should drop source contents for includeSources=false", function() { it("Should drop source contents for includeSources=false", function() {
var result = UglifyJS.minify(read("./test/input/issue-520/input.js"), { var result = UglifyJS.minify(read("./test/input/issue-520/input.js"), {

View File

@ -231,16 +231,15 @@ function run_compress_tests() {
}); });
return false; return false;
} }
var options = U.defaults(test.options, {
warnings: false
});
var warnings_emitted = []; var warnings_emitted = [];
var original_warn_function = U.AST_Node.warn_function;
if (test.expect_warnings) { if (test.expect_warnings) {
U.AST_Node.warn_function = function(text) { var expected_warnings = make_code(test.expect_warnings, {
warnings_emitted.push("WARN: " + text); beautify: false,
}; quote_style: 2, // force double quote to match JSON
if (!options.warnings) options.warnings = true; });
U.AST_Node.log_function(function(text) {
warnings_emitted.push(text);
}, /"INFO: /.test(expected_warnings));
} }
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) { if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
var quoted_props = test.mangle.properties.reserved; var quoted_props = test.mangle.properties.reserved;
@ -252,7 +251,7 @@ function run_compress_tests() {
input.figure_out_scope(test.mangle); input.figure_out_scope(test.mangle);
input.expand_names(test.mangle); input.expand_names(test.mangle);
} }
var cmp = new U.Compressor(options, true); var cmp = new U.Compressor(test.options, true);
var output = cmp.compress(input); var output = cmp.compress(input);
output.figure_out_scope(test.mangle); output.figure_out_scope(test.mangle);
if (test.mangle) { if (test.mangle) {
@ -283,11 +282,6 @@ function run_compress_tests() {
return false; return false;
} }
if (test.expect_warnings) { if (test.expect_warnings) {
U.AST_Node.warn_function = original_warn_function;
var expected_warnings = make_code(test.expect_warnings, {
beautify: false,
quote_style: 2, // force double quote to match JSON
});
warnings_emitted = warnings_emitted.map(function(input) { warnings_emitted = warnings_emitted.map(function(input) {
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/"); return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
}); });