diff --git a/lib/compress.js b/lib/compress.js index 9b6e3369de..eded00c7e7 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1699,6 +1699,19 @@ merge(Compressor.prototype, { continue; } + if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) { + var negated = stat.condition.negate(compressor); + if (negated.print_to_string().length <= stat.condition.print_to_string().length) { + CHANGED = true; + stat = stat.clone(); + stat.condition = negated; + statements[j] = stat.body; + stat.body = next; + statements[i] = stat.transform(compressor); + continue; + } + } + var ab = aborts(stat.alternative); if (can_merge_flow(ab)) { if (ab.label) { diff --git a/test/compress/if_return.js b/test/compress/if_return.js index c56fa04d8b..857406d4aa 100644 --- a/test/compress/if_return.js +++ b/test/compress/if_return.js @@ -396,3 +396,151 @@ if_if_return_return: { } } } + +if_body_return_1: { + options = { + if_return: true, + } + input: { + var c = "PASS"; + function f(a, b) { + if (a) { + if (b) throw new Error(c); + return 42; + } + return true; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect: { + var c = "PASS"; + function f(a, b) { + if (a) { + if (b) throw new Error(c); + return 42; + } + return true; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect_stdout: [ + "true", + "true", + "42", + "PASS", + ] +} + +if_body_return_2: { + options = { + if_return: true, + } + input: { + var c = "PASS"; + function f(a, b) { + if (0 + a) { + if (b) throw new Error(c); + return 42; + } + return true; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect: { + var c = "PASS"; + function f(a, b) { + if (0 + a) { + if (b) throw new Error(c); + return 42; + } + return true; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect_stdout: [ + "true", + "true", + "42", + "PASS", + ] +} + +if_body_return_3: { + options = { + if_return: true, + } + input: { + var c = "PASS"; + function f(a, b) { + if (1 == a) { + if (b) throw new Error(c); + return 42; + } + return true; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect: { + var c = "PASS"; + function f(a, b) { + if (1 != a) return true; + if (b) throw new Error(c); + return 42; + } + console.log(f(0, 0)); + console.log(f(0, 1)); + console.log(f(1, 0)); + try { + f(1, 1); + console.log("FAIL"); + } catch (e) { + console.log(e.message); + } + } + expect_stdout: [ + "true", + "true", + "42", + "PASS", + ] +}