return sym instanceof AST_SymbolLambda && def.scope.name === sym;
});
+ function find_scope(compressor) {
+ var level = 0, node;
+ while (node = compressor.parent(level++)) {
+ if (node.variables) return node;
+ }
+ }
+
function is_lhs_read_only(lhs, compressor) {
if (lhs instanceof AST_This) return true;
if (lhs instanceof AST_SymbolRef) {
&& !fn.pinned()
&& !(fn.name && fn instanceof AST_Function)
&& (exp === fn || !recursive_ref(compressor, def = exp.definition())
- && fn.is_constant_expression(compressor.find_parent(AST_BlockScope)))
+ && fn.is_constant_expression(find_scope(compressor)))
&& (value = can_flatten_body(stat))
&& !fn.contains_this()) {
var replacing = exp === fn || compressor.option("unused") && def.references.length - def.replaced == 1;
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
}
+ function find_variable(compressor, name) {
+ var level = 0, node;
+ while (node = compressor.parent(level++)) {
+ if (node.variables) return node.find_variable(name);
+ }
+ }
+
OPT(AST_Undefined, function(self, compressor) {
if (compressor.option("unsafe_undefined")) {
- var undef = compressor.find_parent(AST_BlockScope).find_variable("undefined");
+ var undef = find_scope(compressor).find_variable("undefined");
if (undef) {
var ref = make_node(AST_SymbolRef, self, {
name : "undefined",
if (lhs && is_atomic(lhs, self)) return self;
if (compressor.option("keep_infinity")
&& !(lhs && !is_atomic(lhs, self))
- && !compressor.find_parent(AST_BlockScope).find_variable("Infinity"))
+ && !find_scope(compressor).find_variable("Infinity"))
return self;
return make_node(AST_Binary, self, {
operator: "/",
OPT(AST_NaN, function(self, compressor) {
var lhs = is_lhs(compressor.self(), compressor.parent());
- if (lhs && !is_atomic(lhs, self)
- || compressor.find_parent(AST_BlockScope).find_variable("NaN")) {
+ if (lhs && !is_atomic(lhs, self) || find_scope(compressor).find_variable("NaN")) {
return make_node(AST_Binary, self, {
operator: "/",
left: make_node(AST_Number, self, {
log("// reduce test pass " + pass + ": " + testcase.length + " bytes");
}
}
- testcase = try_beautify(testcase, minify_options, differs.unminified_result, result_cache, max_timeout);
+ var beautified = U.minify(testcase, {
+ compress: false,
+ mangle: false,
+ output: {
+ beautify: true,
+ braces: true,
+ comments: true,
+ },
+ });
+ testcase = {
+ code: testcase,
+ };
+ if (!beautified.error) {
+ diff = test_for_diff(beautified.code, minify_options, result_cache, max_timeout);
+ if (diff && !diff.timed_out && !diff.error) {
+ testcase = beautified;
+ testcase.code = "// (beautified)\n" + testcase.code;
+ differs = diff;
+ }
+ }
var lines = [ "" ];
if (isNaN(max_timeout)) {
lines.push("// minify error: " + to_comment(strip_color_codes(differs.minified_result.stack)));
return ("" + value).replace(/\s+$/, "");
}
-function try_beautify(testcase, minify_options, expected, result_cache, timeout) {
- var result = U.minify(testcase, {
- compress: false,
- mangle: false,
- output: {
- beautify: true,
- braces: true,
- comments: true,
- },
- });
- if (result.error) return {
- code: testcase,
- };
- var toplevel = sandbox.has_toplevel(minify_options);
- if (isNaN(timeout)) {
- if (!U.minify(result.code, minify_options).error) return {
- code: testcase,
- };
- } else {
- var actual = run_code(result.code, toplevel, result_cache, timeout).result;
- if (!sandbox.same_stdout(expected, actual)) return {
- code: testcase,
- };
- }
- result.code = "// (beautified)\n" + result.code;
- return result;
-}
-
function has_exit(fn) {
var found = false;
var tw = new U.TreeWalker(function(node) {