and: { options = { evaluate: true, side_effects: true, } input: { var a; // compress these a = true && condition; a = 1 && console.log("a"); a = 2 * 3 && 2 * condition; a = 5 == 5 && condition + 3; a = "string" && 4 - condition; a = 5 + "" && condition / 5; a = -4.5 && 6 << condition; a = 6 && 7; a = false && condition; a = NaN && console.log("b"); a = 0 && console.log("c"); a = undefined && 2 * condition; a = null && condition + 3; a = 2 * 3 - 6 && 4 - condition; a = 10 == 7 && condition / 5; a = !"string" && 6 % condition; a = 0 && 7; // don't compress these a = condition && true; a = console.log("a") && 2; a = 4 - condition && "string"; a = 6 << condition && -4.5; a = condition && false; a = console.log("b") && NaN; a = console.log("c") && 0; a = 2 * condition && undefined; a = condition + 3 && null; } expect: { var a; a = condition; a = console.log("a"); a = 2 * condition; a = condition + 3; a = 4 - condition; a = condition / 5; a = 6 << condition; a = 7; a = false; a = NaN; a = 0; a = void 0; a = null; a = 0; a = false; a = false; a = 0; a = condition && true; a = console.log("a") && 2; a = 4 - condition && "string"; a = 6 << condition && -4.5; a = condition && false; a = console.log("b") && NaN; a = console.log("c") && 0; a = 2 * condition && void 0; a = condition + 3 && null; } } or: { options = { evaluate: true, side_effects: true, } input: { var a; // compress these a = true || condition; a = 1 || console.log("a"); a = 2 * 3 || 2 * condition; a = 5 == 5 || condition + 3; a = "string" || 4 - condition; a = 5 + "" || condition / 5; a = -4.5 || 6 << condition; a = 6 || 7; a = false || condition; a = 0 || console.log("b"); a = NaN || console.log("c"); a = undefined || 2 * condition; a = null || condition + 3; a = 2 * 3 - 6 || 4 - condition; a = 10 == 7 || condition / 5; a = !"string" || 6 % condition; a = null || 7; a = console.log(undefined && condition || null); a = console.log(undefined || condition && null); // don't compress these a = condition || true; a = console.log("a") || 2; a = 4 - condition || "string"; a = 6 << condition || -4.5; a = condition || false; a = console.log("b") || NaN; a = console.log("c") || 0; a = 2 * condition || undefined; a = condition + 3 || null; } expect: { var a; a = true; a = 1; a = 6; a = true; a = "string"; a = "5"; a = -4.5; a = 6; a = condition; a = console.log("b"); a = console.log("c"); a = 2 * condition; a = condition + 3; a = 4 - condition; a = condition / 5; a = 6 % condition; a = 7; a = console.log(null); a = console.log(condition && null); a = condition || true; a = console.log("a") || 2; a = 4 - condition || "string"; a = 6 << condition || -4.5; a = condition || false; a = console.log("b") || NaN; a = console.log("c") || 0; a = 2 * condition || void 0; a = condition + 3 || null; } } unary_prefix: { options = { evaluate: true, side_effects: true, } input: { a = !0 && b; a = !0 || b; a = ~1 && b; a = ~1 || b; a = -2 && b; a = -2 || b; a = +3 && b; a = +3 || b; } expect: { a = b; a = !0; a = b; a = -2; a = b; a = -2; a = b; a = 3; } } negative_zero: { options = { evaluate: true, } input: { console.log( -"", - -"", 1 / (-0), 1 / (-"") ); } expect: { console.log( -0, 0, -1/0, -1/0 ); } expect_stdout: true } positive_zero: { options = { evaluate: true, } input: { console.log( +"", + -"", 1 / (+0), 1 / (+"") ); } expect: { console.log( 0, -0, 1/0, 1/0 ); } expect_stdout: true } unsafe_constant: { options = { evaluate: true, unsafe: true, } input: { console.log(true.a, false.a); console.log(true.valueOf(), false.valueOf()); try { console.log(null.a); } catch (e) { console.log("PASS"); } try { console.log(undefined.a); } catch (e) { console.log("PASS"); } } expect: { console.log(void 0, void 0); console.log(true, false); try { console.log(null.a); } catch (e) { console.log("PASS"); } try { console.log((void 0).a); } catch (e) { console.log("PASS"); } } expect_stdout: [ "undefined undefined", "true false", "PASS", "PASS", ] } unsafe_object: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var o = { a: 1 }; console.log( o + 1, o.a + 1, o.b + 1, o.a.b + 1 ); } expect: { var o = { a: 1 }; console.log( o + 1, 2, o.b + 1, NaN ); } expect_stdout: true } unsafe_object_nested: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var o = { a: { b: 1 } }; console.log( o + 1, o.a + 1, o.b + 1, o.a.b + 1 ); } expect: { var o = { a: { b: 1 } }; console.log( o + 1, o.a + 1, o.b + 1, 2 ); } expect_stdout: true } unsafe_object_complex: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var o = { a: { b: 1 }, b: 1 }; console.log( o + 1, o.a + 1, o.b + 1, o.a.b + 1 ); } expect: { var o = { a: { b: 1 }, b: 1 }; console.log( o + 1, o.a + 1, 2, 2 ); } expect_stdout: true } unsafe_object_repeated: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var o = { a: { b: 1 }, a: 1 }; console.log( o + 1, o.a + 1, o.b + 1, o.a.b + 1 ); } expect: { var o = { a: { b: 1 }, a: 1 }; console.log( o + 1, 2, o.b + 1, NaN ); } expect_stdout: true } unsafe_object_accessor: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, unsafe: true, } input: { function f() { var a = { get b() {}, set b() {} }; return {a:a}; } } expect: { function f() { var a = { get b() {}, set b() {} }; return {a:a}; } } } prop_function: { options = { evaluate: true, properties: true, side_effects: true, } input: { console.log( ({a:{b:1},b:function(){}}) + 1, ({a:{b:1},b:function(){}}).a + 1, ({a:{b:1},b:function(){}}).b + 1, ({a:{b:1},b:function(){}}).a.b + 1 ); } expect: { console.log( ({a:{b:1},b:function(){}}) + 1, ({b:1}) + 1, function(){} + 1, 2 ); } expect_stdout: true } unsafe_integer_key: { options = { evaluate: true, unsafe: true, } input: { console.log( ({0:1}) + 1, ({0:1})[0] + 1, ({0:1})["0"] + 1, ({0:1})[1] + 1, ({0:1})[0][1] + 1, ({0:1})[0]["1"] + 1 ); } expect: { console.log( ({0:1}) + 1, 2, 2, ({0:1})[1] + 1, NaN, NaN ); } expect_stdout: true } unsafe_integer_key_complex: { options = { evaluate: true, unsafe: true, } input: { console.log( ({0:{1:1},1:1}) + 1, ({0:{1:1},1:1})[0] + 1, ({0:{1:1},1:1})["0"] + 1, ({0:{1:1},1:1})[1] + 1, ({0:{1:1},1:1})[0][1] + 1, ({0:{1:1},1:1})[0]["1"] + 1 ); } expect: { console.log( ({0:{1:1},1:1}) + 1, "[object Object]1", "[object Object]1", 2, 2, 2 ); } expect_stdout: true } unsafe_float_key: { options = { evaluate: true, unsafe: true, } input: { console.log( ({2.72:1}) + 1, ({2.72:1})[2.72] + 1, ({2.72:1})["2.72"] + 1, ({2.72:1})[3.14] + 1, ({2.72:1})[2.72][3.14] + 1, ({2.72:1})[2.72]["3.14"] + 1 ); } expect: { console.log( ({2.72:1}) + 1, 2, 2, ({2.72:1})[3.14] + 1, NaN, NaN ); } expect_stdout: true } unsafe_float_key_complex: { options = { evaluate: true, unsafe: true, } input: { console.log( ({2.72:{3.14:1},3.14:1}) + 1, ({2.72:{3.14:1},3.14:1})[2.72] + 1, ({2.72:{3.14:1},3.14:1})["2.72"] + 1, ({2.72:{3.14:1},3.14:1})[3.14] + 1, ({2.72:{3.14:1},3.14:1})[2.72][3.14] + 1, ({2.72:{3.14:1},3.14:1})[2.72]["3.14"] + 1 ); } expect: { console.log( "[object Object]1", "[object Object]1", "[object Object]1", 2, 2, 2 ); } expect_stdout: true } unsafe_array: { options = { evaluate: true, unsafe: true, } input: { var a = "PASS"; Array.prototype[1] = a; console.log([, ].length); console.log("" + [, , ]); console.log([1, , 3][1]); console.log([1, 2, 3, a] + 1); console.log([1, 2, 3, 4] + 1); console.log([1, 2, 3, a][0] + 1); console.log([1, 2, 3, 4][0] + 1); console.log([1, 2, 3, 4][6 - 5] + 1); console.log([1, , 3, 4][6 - 5] + 1); console.log([[1, 2], [3, 4]][0] + 1); console.log([[1, 2], [3, 4]][6 - 5][1] + 1); console.log([[1, 2], , [3, 4]][6 - 5][1] + 1); } expect: { var a = "PASS"; Array.prototype[1] = a; console.log([, ].length); console.log("" + [, , ]); console.log([1, , 3][1]); console.log([1, 2, 3, a] + 1); console.log("1,2,3,41"); console.log([1, 2, 3, a][0] + 1); console.log(2); console.log(3); console.log([1, , 3, 4][1] + 1); console.log("1,21"); console.log(5); console.log([[1, 2], , [3, 4]][1][1] + 1); } expect_stdout: [ "1", ",PASS", "PASS", "1,2,3,PASS1", "1,2,3,41", "2", "2", "3", "PASS1", "1,21", "5", "A1", ] } unsafe_string: { options = { evaluate: true, unsafe: true, } input: { console.log( "1234" + 1, "1234"[0] + 1, "1234"[6 - 5] + 1, ("12" + "34")[0] + 1, ("12" + "34")[6 - 5] + 1, [1, 2, 3, 4].join("")[0] + 1 ); } expect: { console.log( "12341", "11", "21", "11", "21", "11" ); } expect_stdout: true } unsafe_array_bad_index: { options = { evaluate: true, unsafe: true, } input: { console.log( [1, 2, 3, 4].a + 1, [1, 2, 3, 4]["a"] + 1, [1, 2, 3, 4][3.14] + 1 ); } expect: { console.log( [1, 2, 3, 4].a + 1, [1, 2, 3, 4]["a"] + 1, [1, 2, 3, 4][3.14] + 1 ); } expect_stdout: true } unsafe_string_bad_index: { options = { evaluate: true, unsafe: true, } input: { console.log( "1234".a + 1, "1234"["a"] + 1, "1234"[3.14] + 1 ); } expect: { console.log( NaN, NaN, NaN ); } expect_stdout: "NaN NaN NaN" } prototype_function: { options = { evaluate: true, properties: true, side_effects: true, } input: { var a = ({valueOf: 0}) < 1; var b = ({toString: 0}) < 1; var c = ({valueOf: 0}) + ""; var d = ({toString: 0}) + ""; var e = (({valueOf: 0}) + "")[2]; var f = (({toString: 0}) + "")[2]; var g = ({valueOf: 0}).valueOf(); var h = ({toString: 0}).toString(); } expect: { var a = ({valueOf: 0}) < 1; var b = ({toString: 0}) < 1; var c = ({valueOf: 0}) + ""; var d = ({toString: 0}) + ""; var e = (({valueOf: 0}) + "")[2]; var f = (({toString: 0}) + "")[2]; var g = 0(); var h = 0(); } } call_args: { options = { evaluate: true, inline: true, reduce_funcs: true, reduce_vars: true, toplevel: true, } input: { var a = 1; console.log(a); +function(a) { return a; }(a); } expect: { var a = 1; console.log(1); +(1, 1); } expect_stdout: true } call_args_drop_param: { options = { evaluate: true, inline: true, keep_fargs: false, reduce_funcs: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = 1; console.log(a); +function(a) { return a; }(a, b); } expect: { console.log(1); +(b, 1); } expect_stdout: true } in_boolean_context: { options = { booleans: true, evaluate: true, sequences: true, side_effects: true, } input: { console.log( !42, !"foo", ![1, 2], !/foo/, !b(42), !b("foo"), !b([1, 2]), !b(/foo/), ![1, foo()], ![1, foo(), 2] ); } expect: { console.log( !1, !1, !1, !1, !b(42), !b("foo"), !b([1, 2]), !b(/foo/), (foo(), !1), (foo(), !1) ); } expect_stdout: true } unsafe_charAt: { options = { evaluate: true, unsafe: true, } input: { console.log( "1234" + 1, "1234".charAt(0) + 1, "1234".charAt(6 - 5) + 1, ("12" + "34").charAt(0) + 1, ("12" + "34").charAt(6 - 5) + 1, [1, 2, 3, 4].join("").charAt(0) + 1 ); } expect: { console.log( "12341", "11", "21", "11", "21", "11" ); } expect_stdout: true } unsafe_charAt_bad_index: { options = { evaluate: true, unsafe: true, } input: { console.log( "1234".charAt() + 1, "1234".charAt("a") + 1, "1234".charAt(3.14) + 1 ); } expect: { console.log( "11", "11", "41" ); } expect_stdout: true } unsafe_charAt_noop: { options = { evaluate: true, unsafe: true, } input: { console.log( s.charAt(0), "string".charAt(x), (typeof x).charAt() ); } expect: { console.log( s[0], "string"[0 | x], (typeof x)[0] ); } } issue_1649: { options = { evaluate: true, } input: { console.log(-1 + -1); } expect: { console.log(-2); } expect_stdout: "-2"; } issue_1760_1: { options = { evaluate: true, } input: { !function(a) { try { throw 0; } catch (NaN) { a = +"foo"; } console.log(a); }(); } expect: { !function(a) { try { throw 0; } catch (NaN) { a = 0 / 0; } console.log(a); }(); } expect_stdout: "NaN" } issue_1760_2: { options = { evaluate: true, keep_infinity: true, } input: { !function(a) { try { throw 0; } catch (Infinity) { a = 123456789 / 0; } console.log(a); }(); } expect: { !function(a) { try { throw 0; } catch (Infinity) { a = 1 / 0; } console.log(a); }(); } expect_stdout: "Infinity" } delete_expr_1: { options = { booleans: true, evaluate: true, } input: { console.log(delete undefined); console.log(delete void 0); console.log(delete Infinity); console.log(delete (1 / 0)); console.log(delete NaN); console.log(delete (0 / 0)); } expect: { console.log(delete undefined); console.log((void 0, !0)); console.log(delete Infinity); console.log((1 / 0, !0)); console.log(delete NaN); console.log((0 / 0, !0)); } expect_stdout: true } delete_expr_2: { options = { booleans: true, evaluate: true, keep_infinity: true, } input: { console.log(delete undefined); console.log(delete void 0); console.log(delete Infinity); console.log(delete (1 / 0)); console.log(delete NaN); console.log(delete (0 / 0)); } expect: { console.log(delete undefined); console.log((void 0, !0)); console.log(delete Infinity); console.log((1 / 0, !0)); console.log(delete NaN); console.log((0 / 0, !0)); } expect_stdout: true } delete_binary_1: { options = { booleans: true, evaluate: true, side_effects: true, } input: { console.log(delete (true && undefined)); console.log(delete (true && void 0)); console.log(delete (true && Infinity)); console.log(delete (true && (1 / 0))); console.log(delete (true && NaN)); console.log(delete (true && (0 / 0))); } expect: { console.log(!0); console.log(!0); console.log(!0); console.log(!0); console.log(!0); console.log(!0); } expect_stdout: true } delete_binary_2: { options = { booleans: true, evaluate: true, keep_infinity: true, side_effects: true, } input: { console.log(delete (false || undefined)); console.log(delete (false || void 0)); console.log(delete (false || Infinity)); console.log(delete (false || (1 / 0))); console.log(delete (false || NaN)); console.log(delete (false || (0 / 0))); } expect: { console.log(!0); console.log(!0); console.log(!0); console.log(!0); console.log(!0); console.log(!0); } expect_stdout: true } Infinity_NaN_undefined_LHS: { beautify = { beautify: true, } input: { function f() { Infinity = Infinity; ++Infinity; Infinity--; NaN *= NaN; ++NaN; NaN--; undefined |= undefined; ++undefined; undefined--; } } expect_exact: [ "function f() {", " Infinity = 1 / 0;", " ++Infinity;", " Infinity--;", " NaN *= NaN;", " ++NaN;", " NaN--;", " undefined |= void 0;", " ++undefined;", " undefined--;", "}", ] } issue_1964_1: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, unsafe_regexp: false, unused: true, } input: { function f() { var long_variable_name = /\s/; console.log(long_variable_name.source); return "a b c".split(long_variable_name)[1]; } console.log(f()); } expect: { function f() { var long_variable_name = /\s/; console.log(long_variable_name.source); return "a b c".split(long_variable_name)[1]; } console.log(f()); } expect_stdout: [ "\\s", "b", ] } issue_1964_2: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, unsafe_regexp: true, unused: true, } input: { function f() { var long_variable_name = /\s/; console.log(long_variable_name.source); return "a b c".split(long_variable_name)[1]; } console.log(f()); } expect: { function f() { console.log(/\s/.source); return "a b c".split(/\s/)[1]; } console.log(f()); } expect_stdout: [ "\\s", "b", ] } array_slice_index: { options = { evaluate: true, unsafe: true, } input: { console.log([1,2,3].slice(1)[1]); } expect: { console.log(3); } expect_stdout: "3" } string_charCodeAt: { options = { evaluate: true, unsafe: true, } input: { console.log("foo".charCodeAt("bar".length)); } expect: { console.log(NaN); } expect_stdout: "NaN" } issue_2207_1: { options = { evaluate: true, unsafe: true, } input: { console.log(String.fromCharCode(65)); console.log(Math.max(3, 6, 2, 7, 3, 4)); console.log(Math.cos(1.2345)); console.log(Math.cos(1.2345) - Math.sin(4.321)); console.log(Math.pow(Math.PI, Math.E - Math.LN10).toFixed(15)); } expect: { console.log("A"); console.log(7); console.log(Math.cos(1.2345)); console.log(1.2543732512566947); console.log("1.609398451447204"); } expect_stdout: true } issue_2207_2: { options = { evaluate: true, unsafe: true, } input: { console.log(Math.E); console.log(Math.LN10); console.log(Math.LN2); console.log(Math.LOG2E); console.log(Math.LOG10E); console.log(Math.PI); console.log(Math.SQRT1_2); console.log(Math.SQRT2); } expect: { console.log(Math.E); console.log(Math.LN10); console.log(Math.LN2); console.log(Math.LOG2E); console.log(Math.LOG10E); console.log(Math.PI); console.log(Math.SQRT1_2); console.log(Math.SQRT2); } expect_stdout: true } issue_2207_3: { options = { evaluate: true, unsafe: true, } input: { console.log(Number.MAX_VALUE); console.log(Number.MIN_VALUE); console.log(Number.NaN); console.log(Number.NEGATIVE_INFINITY); console.log(Number.POSITIVE_INFINITY); } expect: { console.log(Number.MAX_VALUE); console.log(5e-324); console.log(NaN); console.log(-1/0); console.log(1/0); } expect_stdout: true } issue_2231_1: { options = { evaluate: true, unsafe: true, } input: { console.log(Object.keys(void 0)); } expect: { console.log(Object.keys(void 0)); } expect_stdout: true expect_warnings: [ "WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1,20]", ] } issue_2231_2: { options = { evaluate: true, unsafe: true, } input: { console.log(Object.getOwnPropertyNames(null)); } expect: { console.log(Object.getOwnPropertyNames(null)); } expect_stdout: true expect_warnings: [ "WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1,20]", ] } issue_2231_3: { options = { evaluate: true, unsafe: true, } input: { console.log(Object.keys({ foo: "bar" })[0]); } expect: { console.log("foo"); } expect_stdout: "foo" } self_comparison_1: { options = { evaluate: true, reduce_funcs: true, reduce_vars: true, toplevel: true, unsafe: true, unused: true, } input: { var o = { n: NaN }; console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n); } expect: { console.log("number", false, false, true, true); } expect_stdout: "number false false true true" } self_comparison_2: { options = { evaluate: true, hoist_props: true, passes: 2, reduce_funcs: true, reduce_vars: true, toplevel: true, unused: true, } input: { var o = { n: NaN }; console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n); } expect: { console.log("number", false, false, true, true); } expect_stdout: "number false false true true" } issue_2535_1: { options = { booleans: true, evaluate: true, sequences: true, side_effects: true, } input: { if ((x() || true) || y()) z(); if ((x() || true) && y()) z(); if ((x() && true) || y()) z(); if ((x() && true) && y()) z(); if ((x() || false) || y()) z(); if ((x() || false) && y()) z(); if ((x() && false) || y()) z(); if ((x() && false) && y()) z(); } expect: { if (x(), 1) z(); if (x(), y()) z(); if (x() || y()) z(); if (x() && y()) z(); if (x() || y()) z(); if (x() && y()) z(); if (x(), y()) z(); if (x(), 0) z(); } } issue_2535_2: { options = { booleans: true, evaluate: true, sequences: true, side_effects: true, } input: { (x() || true) || y(); (x() || true) && y(); (x() && true) || y(); (x() && true) && y(); (x() || false) || y(); (x() || false) && y(); (x() && false) || y(); (x() && false) && y(); } expect: { x(), x(), y(), x() || y(), x() && y(), x() || y(), x() && y(), x(), y(), x(); } } issue_2535_3: { options = { booleans: true, evaluate: true, } input: { console.log(Object(1) && 1 && 2); console.log(Object(1) && true && 1 && 2 && Object(2)); console.log(Object(1) && true && 1 && null && 2 && Object(2)); console.log(2 == Object(1) || 0 || void 0 || null); console.log(2 == Object(1) || 0 || void 0 || null || Object(2)); console.log(2 == Object(1) || 0 || void 0 || "ok" || null || Object(2)); } expect: { console.log(Object(1) && 2); console.log(Object(1) && Object(2)); console.log(Object(1) && null); console.log(2 == Object(1) || null); console.log(2 == Object(1) || Object(2)); console.log(2 == Object(1) || "ok"); } expect_stdout: true expect_warnings: [ "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1,20]", "WARN: Dropping side-effect-free && [test/compress/evaluate.js:2,20]", "WARN: Dropping side-effect-free && [test/compress/evaluate.js:3,20]", "WARN: Condition left of && always false [test/compress/evaluate.js:3,20]", "WARN: Dropping side-effect-free || [test/compress/evaluate.js:4,20]", "WARN: Dropping side-effect-free || [test/compress/evaluate.js:5,20]", "WARN: Dropping side-effect-free || [test/compress/evaluate.js:6,20]", "WARN: Condition left of || always true [test/compress/evaluate.js:6,20]", ] } issue_2822: { options = { evaluate: true, unsafe: true, } input: { console.log([ function() {}, "PASS", "FAIL" ][1]); } expect: { console.log("PASS"); } expect_stdout: "PASS" } string_case: { options = { evaluate: true, unsafe: true, } input: { console.log("İ".toLowerCase().charCodeAt(0)); console.log("I".toLowerCase().charCodeAt(0)); console.log("Ş".toLowerCase().charCodeAt(0)); console.log("Ğ".toLowerCase().charCodeAt(0)); console.log("Ü".toLowerCase().charCodeAt(0)); console.log("Ö".toLowerCase().charCodeAt(0)); console.log("Ç".toLowerCase().charCodeAt(0)); console.log("i".toUpperCase().charCodeAt(0)); console.log("ı".toUpperCase().charCodeAt(0)); console.log("ş".toUpperCase().charCodeAt(0)); console.log("ğ".toUpperCase().charCodeAt(0)); console.log("ü".toUpperCase().charCodeAt(0)); console.log("ö".toUpperCase().charCodeAt(0)); console.log("ç".toUpperCase().charCodeAt(0)); } expect: { console.log(105); console.log(105); console.log(351); console.log(287); console.log(252); console.log(246); console.log(231); console.log(73); console.log(73); console.log(350); console.log(286); console.log(220); console.log(214); console.log(199); } expect_stdout: [ "105", "105", "351", "287", "252", "246", "231", "73", "73", "350", "286", "220", "214", "199", ] } issue_2916_1: { options = { evaluate: true, reduce_vars: true, unsafe: true, } input: { var c = "PASS"; (function(a, b) { (function(d) { d[0] = 1; })(b); a == b && (c = "FAIL"); })("", []); console.log(c); } expect: { var c = "PASS"; (function(a, b) { (function(d) { d[0] = 1; })(b); a == b && (c = "FAIL"); })("", []); console.log(c); } expect_stdout: "PASS" } issue_2916_2: { options = { collapse_vars: true, evaluate: true, inline: true, reduce_vars: true, side_effects: true, unsafe: true, unused: true, } input: { var c = "FAIL"; (function(b) { (function(d) { d[0] = 1; })(b); +b && (c = "PASS"); })([]); console.log(c); } expect: { var c = "FAIL"; (function(b) { b[0] = 1; +b && (c = "PASS"); })([]); console.log(c); } expect_stdout: "PASS" } issue_2919: { options = { evaluate: true, unsafe: true, } input: { console.log([ function() {} ].toString()); } expect: { console.log("function(){}"); } } issue_2926_1: { options = { evaluate: true, reduce_vars: true, unsafe: true, } input: { (function f(a) { console.log(f.name.length, f.length); })(); } expect: { (function f(a) { console.log(1, 1); })(); } expect_stdout: "1 1" } issue_2926_2: { options = { evaluate: true, unsafe: true, } input: { console.log(typeof function() {}.valueOf()); } expect: { console.log("function"); } expect_stdout: "function" } issue_2968_1: { options = { collapse_vars: true, evaluate: true, inline: true, passes: 2, reduce_vars: true, unused: true, } input: { var c = "FAIL"; (function() { (function(a, b) { a <<= 0; a && (a[(c = "PASS", 0 >>> (b += 1))] = 0); })(42, -42); })(); console.log(c); } expect: { var c = "FAIL"; (function() { a = 42, void ((a <<= 0) && (a[(c = "PASS", 0)] = 0)); var a; })(); console.log(c); } expect_stdout: "PASS" } issue_2968_2: { options = { assignments: true, collapse_vars: true, evaluate: true, inline: true, passes: 2, reduce_vars: true, side_effects: true, unused: true, } input: { var c = "FAIL"; (function() { (function(a, b) { a <<= 0; a && (a[(c = "PASS", 0 >>> (b += 1))] = 0); })(42, -42); })(); console.log(c); } expect: { var c = "FAIL"; (function() { a = 42, ((a <<= 0) && (a[(c = "PASS", 0)] = 0)); var a; })(); console.log(c); } expect_stdout: "PASS" } truthy_conditionals: { options = { conditionals: true, evaluate: true, } input: { if (a = {}) x(); (b = /foo/) && y(); (c = function() {}) || z(); } expect: { a = {}, x(); b = /foo/, y(); c = function() {}; } } truthy_loops: { options = { evaluate: true, loops: true, } input: { while ([]) x(); do { y(); } while(a = {}); } expect: { for (;;) { []; x(); } for (;;) { y(); a = {}; } } } if_increment: { options = { evaluate: true, reduce_vars: true, unused: true, } input: { console.log(function(a) { if (console) return ++a; }(0)); } expect: { console.log(function(a) { if (console) return 1; }()); } expect_stdout: "1" } try_increment: { options = { evaluate: true, reduce_vars: true, unused: true, } input: { console.log(function(a) { try { return ++a; } catch (e) {} }(0)); } expect: { console.log(function(a) { try { return 1; } catch (e) {} }()); } expect_stdout: "1" } unsafe_escaped: { options = { evaluate: true, inline: true, passes: 3, reduce_vars: true, side_effects: true, unsafe: true, unused: true, } input: { (function(a) { console.log(function(index) { return a[index]; }(function(term) { return a.indexOf(term); }("PASS"))); })([ "PASS" ]); } expect: { console.log("PASS"); } expect_stdout: "PASS" } unsafe_string_replace: { options = { evaluate: true, unsafe: true, } input: { "foo".replace("f", function() { console.log("PASS"); }); } expect: { "foo".replace("f", function() { console.log("PASS"); }); } expect_stdout: "PASS" } issue_3387_1: { options = { evaluate: true, } input: { console.log(1 + (2 + "3"[4])); } expect: { console.log(1 + (2 + "3"[4])); } expect_stdout: "NaN" } issue_3387_2: { options = { evaluate: true, unsafe: true, } input: { console.log(1 + (2 + "3"[4])); } expect: { console.log(NaN); } expect_stdout: "NaN" } simple_function_1: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function sum(a, b) { return a + b; } console.log(sum(1, 2) * sum(3, 4)); } expect: { console.log(21); } expect_stdout: "21" } simple_function_2: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var sum = function(a, b) { return a + b; } console.log(sum(1, 2) * sum(3, 4)); } expect: { console.log(21); } expect_stdout: "21" } recursive_function_1: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function factorial(a) { return a > 0 ? a * factorial(a - 1) : 1; } console.log(factorial(5)); } expect: { console.log(function factorial(a) { return a > 0 ? a * factorial(a - 1) : 1; }(5)); } expect_stdout: "120" } recursive_function_2: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var factorial = function(a) { return a > 0 ? a * factorial(a - 1) : 1; } console.log(factorial(5)); } expect: { var factorial = function(a) { return a > 0 ? a * factorial(a - 1) : 1; } console.log(factorial(5)); } expect_stdout: "120" } issue_3558: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { function f(a) { return 1 + --a; } console.log(f(true), f(false)); } expect: { function f(a) { return 1 + --a; } console.log(1, 0); } expect_stdout: "1 0" } issue_3568: { options = { evaluate: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var a = 0; function f(b) { return b && b.p; } console.log(f(++a + f())); } expect: { var a = 0; function f(b) { return b && b.p; } console.log(NaN); } expect_stdout: "NaN" } conditional_function: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { function f(a) { return a && "undefined" != typeof A ? A : 42; } console.log(f(0), f(1)); } expect: { function f(a) { return a && "undefined" != typeof A ? A : 42; } console.log(42, f(1)); } expect_stdout: "42 42" } best_of_evaluate: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function d(x, y) { return x / y; } console.log(0 / 3, 1 / 64, 4 / 7, 7 / 7); console.log(d(0, 3), d(1, 64), d(4, 7), d(7, 7)); } expect: { function d(x, y) { return x / y; } console.log(0, 1 / 64, 4 / 7, 1); console.log(0, .015625, d(4, 7), 1); } expect_stdout: [ "0 0.015625 0.5714285714285714 1", "0 0.015625 0.5714285714285714 1", ] } eager_evaluate: { options = { evaluate: "eager", reduce_vars: true, toplevel: true, unused: true, } input: { function d(x, y) { return x / y; } console.log(0 / 3, 1 / 64, 4 / 7, 7 / 7); console.log(d(0, 3), d(1, 64), d(4, 7), d(7, 7)); } expect: { console.log(0, .015625, .5714285714285714, 1); console.log(0, .015625, .5714285714285714, 1); } expect_stdout: [ "0 0.015625 0.5714285714285714 1", "0 0.015625 0.5714285714285714 1", ] } threshold_evaluate_default: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function b(x) { return x + x + x; } console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK")))); } expect: { function b(x) { return x + x + x; } console.log("111", 6, b(b(b("ABCDEFGHIJK")))); } expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK" } threshold_evaluate_30: { options = { evaluate: 30, reduce_vars: true, toplevel: true, unused: true, } input: { function b(x) { return x + x + x; } console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK")))); } expect: { function b(x) { return x + x + x; } console.log("111", 6, b(b("ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"))); } expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK" } threshold_evaluate_100: { options = { evaluate: 100, reduce_vars: true, toplevel: true, unused: true, } input: { function b(x) { return x + x + x; } console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK")))); } expect: { function b(x) { return x + x + x; } console.log("111", 6, b("ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK")); } expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK" } threshold_evaluate_999: { options = { evaluate: 999, reduce_vars: true, toplevel: true, unused: true, } input: { function b(x) { return x + x + x; } console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK")))); } expect: { console.log("111", 6, "ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"); } expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK" } collapse_vars_regexp: { options = { booleans: true, collapse_vars: true, comparisons: true, conditionals: true, dead_code: true, evaluate: true, hoist_funs: true, if_return: true, join_vars: true, keep_fargs: true, loops: false, reduce_funcs: true, reduce_vars: true, side_effects: true, unsafe_regexp: true, unused: true, } input: { function f1() { var k = 9; var rx = /[A-Z]+/; return [rx, k]; } function f2() { var rx = /ab*/g; return function(s) { return rx.exec(s); }; } function f3() { var rx = /ab*/g; return function() { return rx; }; } (function() { var result; var s = "acdabcdeabbb"; var rx = /ab*/g; while (result = rx.exec(s)) console.log(result[0]); })(); (function() { var result; var s = "acdabcdeabbb"; var rx = f2(); while (result = rx(s)) console.log(result[0]); })(); (function() { var result; var s = "acdabcdeabbb"; var rx = f3(); while (result = rx().exec(s)) console.log(result[0]); })(); } expect: { function f1() { return [/[A-Z]+/, 9]; } function f2() { var rx = /ab*/g; return function(s) { return rx.exec(s); }; } function f3() { var rx = /ab*/g; return function() { return rx; }; } (function() { var result, rx = /ab*/g; while (result = rx.exec("acdabcdeabbb")) console.log(result[0]); })(); (function() { var result, rx = f2(); while (result = rx("acdabcdeabbb")) console.log(result[0]); })(); (function() { var result, rx = f3(); while (result = rx().exec("acdabcdeabbb")) console.log(result[0]); })(); } expect_stdout: [ "a", "ab", "abbb", "a", "ab", "abbb", "a", "ab", "abbb", ] } issue_3738: { options = { evaluate: true, } input: { console.log(1 / (0 + ([] - 1) % 1)); } expect: { console.log(1 / (0 + ([] - 1) % 1)); } expect_stdout: "Infinity" } issue_3755: { options = { booleans: true, evaluate: true, unsafe: true, unsafe_math: true, } input: { console.log((/4/.exec(1 + (!0 - 5 / "23")) || 0).p); } expect: { console.log((/4/.exec(!0 - 5 / "23" + 1), 0).p); } expect_stdout: "undefined" } void_side_effects: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = void console.log("PASS"); console.log(a); } expect: { console.log("PASS"); console.log(void 0); } expect_stdout: [ "PASS", "undefined", ] } no_returns: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = function() { console.log("PASS"); }(); console.log(a); } expect: { (function() { console.log("PASS"); })(); console.log(void 0); } expect_stdout: [ "PASS", "undefined", ] } void_returns: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = function f() { function g(b) { if (b) console.log("FAIL"); } while (1) { console.log("PASS"); try { if (console) return; } catch (e) { return g(e); } } }(); console.log(a); } expect: { (function() { function g(b) { if (b) console.log("FAIL"); } while (1) { console.log("PASS"); try { if (console) return; } catch (e) { return g(e); } } })(); console.log(void 0); } expect_stdout: [ "PASS", "undefined", ] } void_returns_recursive: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = function f() { function g(b) { return f(); } while (1) { console.log("PASS"); try { if (console) return; } catch (e) { return g(e); } } }(); console.log(a); } expect: { var a = function f() { function g(b) { return f(); } while (1) { console.log("PASS"); try { if (console) return; } catch (e) { return g(); } } }(); console.log(a); } expect_stdout: [ "PASS", "undefined", ] } issue_3878_1: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var b = function(a) { return (a = 0) == (a && this > (a += 0)); }(); console.log(b ? "PASS" : "FAIL"); } expect: { console.log(true ? "PASS" : "FAIL"); } expect_stdout: "PASS" } issue_3878_2: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { var a = "foo"; a++ + a; a && a; console.log(a); } expect: { var a = "foo"; a++ + a; a; console.log(a); } expect_stdout: "NaN" } issue_3882: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function f(a) { return console.log(a++), a && this; } var b = f(); console.log(b); } expect: { var b = function(a) { return console.log(a++), a && this; }(); console.log(b); } expect_stdout: [ "NaN", "NaN", ] } issue_3887: { options = { evaluate: true, reduce_vars: true, unused: true, } input: { (function(b) { try { b-- && console.log("PASS"); } catch (a_2) {} })(1); } expect: { (function(b) { try { 1, console.log("PASS"); } catch (a_2) {} })(); } expect_stdout: "PASS" } issue_3903: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = "PASS"; function f(b, c) { return console, c; } var d = f(f(), a = a); console.log(d); } expect: { function f(b, c) { return console, c; } f(f(), "PASS"); console.log("PASS"); } expect_stdout: "PASS" } issue_3905: { options = { evaluate: true, passes: 2, unused: true, } input: { (function(a, a) { return console.log(a = 0), a && console.log("FAIL"); })("foo", 42); } expect: { (function(a, a) { return console.log(a = 0), a && console.log("FAIL"); })("foo", 42); } expect_stdout: "0" } issue_3920: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { var a = function(b) { return (b[b = 0] = 0) >= (b ? 0 : 1); }("foo"); console.log(a); } expect: { (function(b) { "foo"[0] = 0; })(); console.log(false); } expect_stdout: "false" } inlined_increment_prefix: { options = { evaluate: true, inline: true, reduce_vars: true, toplevel: true, } input: { var a = 0; (function() { ++a; })(); console.log(a += 0); } expect: { var a = 0; void ++a; console.log(1); } expect_stdout: "1" } inlined_increment_postfix: { options = { evaluate: true, inline: true, reduce_vars: true, toplevel: true, } input: { var a = 0; (function() { a++; })(); console.log(a += 0); } expect: { var a = 0; void a++; console.log(1); } expect_stdout: "1" } compound_assignment_to_property: { options = { evaluate: true, unsafe: true, } input: { 1 + (0..p >>= 0) && console.log("PASS"); } expect: { 1 + (0..p >>= 0), console.log("PASS"); } expect_stdout: "PASS" } issue_2208_assign: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { a = 42; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect: { a = 42; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect_stdout: "42" } issue_2208_postfix: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { a = 41; a++; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect: { a = 41; a++; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect_stdout: "42" } issue_2208_prefix: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { a = 43; --a; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect: { a = 43; --a; console.log({ p: function() { return function() { return this.a; }(); } }.p()); } expect_stdout: "42" } issue_3933: { options = { evaluate: true, reduce_vars: true, unused: true, } input: { (function(a, b) { a && (b ^= 1) && console.log("PASS"); })(1); } expect: { (function(a, b) { 1, 1, console.log("PASS"); })(); } expect_stdout: "PASS" } issue_3935: { options = { evaluate: true, } input: { console.log(function f(a) { return a++; }()); } expect: { console.log(NaN); } expect_stdout: "NaN" } issue_3937: { options = { conditionals: true, evaluate: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var a = 123; (a++ + (b = a))[b] ? 0 ? a : b : 0 ? a : b; console.log(a, b); } expect: { var a = 123; (a++ + (b = a))[b], 0, b; console.log(a, b); } expect_stdout: "124 124" } issue_3944: { options = { collapse_vars: true, evaluate: true, inline: true, reduce_vars: true, unused: true, } input: { (function() { function f() { while (function() { var a = 0 == (b && b.p), b = console.log(a); }()); f; } f(); })(); } expect: { void function f() { while (a = 0 == (a = void 0), console.log(a), void 0); var a; f; }(); } expect_stdout: "false" } issue_3953: { options = { evaluate: true, reduce_vars: true, } input: { function f(a) { (a += 0 * (a = 0)) && console.log("PASS"); } f(1); } expect: { function f(a) { (a += 0 * (a = 0)) && console.log("PASS"); } f(1); } expect_stdout: "PASS" } issue_3988: { options = { evaluate: true, reduce_vars: true, toplevel: true, unsafe: true, unused: true, } input: { function f(b) { return ("" + (b &= 0))[b && this]; } var a = f(); console.log(a); } expect: { var a = function(b) { return ("" + (b &= 0))[b && this]; }(); console.log(a); } expect_stdout: "0" } operator_in: { options = { evaluate: true, unsafe: true, } input: { Object.prototype.PASS = 0; console.log(0 in [ 1 ]); console.log(0 in [ , ]); console.log(0 / 0 in { NaN: 2 }); console.log("PASS" in { }); console.log("FAIL" in { }); console.log("toString" in { }); console.log("toString" in { toString: 3 }); } expect: { Object.prototype.PASS = 0; console.log(true); console.log(0 in [ , ]); console.log(true); console.log("PASS" in { }); console.log("FAIL" in { }); console.log("toString" in { }); console.log(true); } expect_stdout: [ "true", "false", "true", "true", "false", "true", "true", ] } issue_3997: { options = { evaluate: true, reduce_vars: true, toplevel: true, } input: { var a = function f(b) { return b[b += this] = b; }(0); console.log(typeof a); } expect: { var a = function f(b) { return b[b += this] = b; }(0); console.log(typeof a); } expect_stdout: "string" } issue_4035: { options = { evaluate: true, reduce_vars: true, } input: { var a = 0; (function() { var b = --a; console.log(delete (0 + b)); console.log(delete (1 * b)); console.log(delete (b + 0)); console.log(delete (b - 0)); console.log(delete (b / 1)); })(); } expect: { var a = 0; (function() { var b = --a; console.log((0 + b, true)); console.log((1 * b, true)); console.log((0 + b, true)); console.log((b - 0, true)); console.log((b / 1, true)); })(); } expect_stdout: [ "true", "true", "true", "true", "true", ] } issue_4067: { options = { evaluate: true, reduce_vars: true, unsafe: true, } input: { (function(a) { (function(b) { b[0] += 0; console.log(+a); })(a); })([]); } expect: { (function(a) { (function(b) { b[0] += 0; console.log(+a); })(a); })([]); } expect_stdout: "NaN" } issue_4077: { options = { evaluate: true, unsafe: true, } input: { console.log((a = []) - (a[0]++, 1) || "PASS"); } expect: { console.log((a = []) - (a[0]++, 1) || "PASS"); } expect_stdout: "PASS" } issue_4119_1: { options = { conditionals: true, dead_code: true, evaluate: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var a, b; b = a = []; a[0] += 0; if (+b + 1) { console.log("FAIL"); } else { console.log("PASS"); } } expect: { var a, b; b = a = []; a[0] += 0; +b + 1 ? console.log("FAIL") : console.log("PASS"); } expect_stdout: "PASS" } issue_4119_2: { options = { conditionals: true, evaluate: true, reduce_vars: true, unsafe: true, } input: { var a; (function(b) { a[0] += 0; console.log(+b + 1 ? "FAIL" : "PASS"); })(a = []); } expect: { var a; (function(b) { a[0] += 0; console.log(+b + 1 ? "FAIL" : "PASS"); })(a = []); } expect_stdout: "PASS" } issue_4119_3: { options = { conditionals: true, evaluate: true, reduce_vars: true, toplevel: true, unsafe: true, } input: { var a, b; b = a = { p: 42, }; delete a.p; console.log(b.p ? "FAIL" : "PASS"); } expect: { var a, b; b = a = { p: 42, }; delete a.p; console.log(b.p ? "FAIL" : "PASS"); } expect_stdout: "PASS" } issue_4119_4: { options = { booleans: true, conditionals: true, evaluate: true, reduce_vars: true, toplevel: true, } input: { var a, b; b = a = { p: 42, }; delete a.p; console.log(!b ? "FAIL" : "PASS"); } expect: { var a, b; b = a = { p: 42, }; delete a.p; console.log((b, 0, "PASS")); } expect_stdout: "PASS" } issue_4214: { options = { evaluate: true, reduce_vars: true, toplevel: true, unused: true, } input: { function f(a) { return function() { try { return a; } finally { var b = 0; } }(a++ && this()); } var c = f(); console.log(c); } expect: { var c = function(a) { return function() { try { return a; } finally {} }(a++ && this()); }(); console.log(c); } expect_stdout: "NaN" }