diff options
-rw-r--r-- | lib/compress.js | 19 | ||||
-rw-r--r-- | test/compress/dead-code.js | 236 | ||||
-rw-r--r-- | test/compress/drop-unused.js | 12 | ||||
-rw-r--r-- | test/compress/side_effects.js | 277 |
4 files changed, 286 insertions, 258 deletions
diff --git a/lib/compress.js b/lib/compress.js index c00b9f07..e277e9a1 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2872,9 +2872,11 @@ merge(Compressor.prototype, { } function convert_to_predicate(obj) { + var map = Object.create(null); Object.keys(obj).forEach(function(key) { - obj[key] = makePredicate(obj[key]); + map[key] = makePredicate(obj[key]); }); + return map; } AST_Lambda.DEFMETHOD("first_statement", function() { @@ -2897,7 +2899,7 @@ merge(Compressor.prototype, { "toString", "valueOf", ]; - var native_fns = { + var native_fns = convert_to_predicate({ Array: [ "indexOf", "join", @@ -2933,9 +2935,8 @@ merge(Compressor.prototype, { "toUpperCase", "trim", ].concat(object_fns), - }; - convert_to_predicate(native_fns); - var static_fns = { + }); + var static_fns = convert_to_predicate({ Array: [ "isArray", ], @@ -2975,8 +2976,7 @@ merge(Compressor.prototype, { String: [ "fromCharCode", ], - }; - convert_to_predicate(static_fns); + }); // methods to evaluate a constant expression (function(def) { @@ -3199,7 +3199,7 @@ merge(Compressor.prototype, { Object: Object, String: String, }; - var static_values = { + var static_values = convert_to_predicate({ Math: [ "E", "LN10", @@ -3217,8 +3217,7 @@ merge(Compressor.prototype, { "NEGATIVE_INFINITY", "POSITIVE_INFINITY", ], - }; - convert_to_predicate(static_values); + }); var regexp_props = makePredicate("global ignoreCase multiline source"); def(AST_PropAccess, function(compressor, cached, depth) { if (compressor.option("unsafe")) { diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js index 627630ab..024d710b 100644 --- a/test/compress/dead-code.js +++ b/test/compress/dead-code.js @@ -141,207 +141,6 @@ try_catch_finally: { ] } -accessor: { - options = { - side_effects: true, - } - input: { - ({ - get a() {}, - set a(v){ - this.b = 2; - }, - b: 1 - }); - } - expect: {} -} - -issue_2233_1: { - options = { - pure_getters: "strict", - side_effects: true, - unsafe: true, - } - input: { - Array.isArray; - Boolean; - console.log; - Date; - decodeURI; - decodeURIComponent; - encodeURI; - encodeURIComponent; - Error.name; - escape; - eval; - EvalError; - Function.length; - isFinite; - isNaN; - JSON; - Math.random; - Number.isNaN; - parseFloat; - parseInt; - RegExp; - Object.defineProperty; - String.fromCharCode; - RangeError; - ReferenceError; - SyntaxError; - TypeError; - unescape; - URIError; - } - expect: {} - expect_stdout: true -} - -global_timeout_and_interval_symbols: { - options = { - pure_getters: "strict", - side_effects: true, - unsafe: true, - } - input: { - // These global symbols do not exist in the test sandbox - // and must be tested separately. - clearInterval; - clearTimeout; - setInterval; - setTimeout; - } - expect: {} -} - -issue_2233_2: { - options = { - pure_getters: "strict", - reduce_funcs: true, - reduce_vars: true, - side_effects: true, - unsafe: true, - unused: true, - } - input: { - var RegExp; - Array.isArray; - RegExp; - UndeclaredGlobal; - function foo() { - var Number; - AnotherUndeclaredGlobal; - Math.sin; - Number.isNaN; - } - } - expect: { - var RegExp; - UndeclaredGlobal; - function foo() { - var Number; - AnotherUndeclaredGlobal; - Number.isNaN; - } - } -} - -issue_2233_3: { - options = { - pure_getters: "strict", - reduce_funcs: true, - reduce_vars: true, - side_effects: true, - toplevel: true, - unsafe: true, - unused: true, - } - input: { - var RegExp; - Array.isArray; - RegExp; - UndeclaredGlobal; - function foo() { - var Number; - AnotherUndeclaredGlobal; - Math.sin; - Number.isNaN; - } - } - expect: { - UndeclaredGlobal; - } -} - -global_fns: { - options = { - side_effects: true, - unsafe: true, - } - input: { - Boolean(1, 2); - decodeURI(1, 2); - decodeURIComponent(1, 2); - Date(1, 2); - encodeURI(1, 2); - encodeURIComponent(1, 2); - Error(1, 2); - escape(1, 2); - EvalError(1, 2); - isFinite(1, 2); - isNaN(1, 2); - Number(1, 2); - Object(1, 2); - parseFloat(1, 2); - parseInt(1, 2); - RangeError(1, 2); - ReferenceError(1, 2); - String(1, 2); - SyntaxError(1, 2); - TypeError(1, 2); - unescape(1, 2); - URIError(1, 2); - try { - Function(1, 2); - } catch (e) { - console.log(e.name); - } - try { - RegExp(1, 2); - } catch (e) { - console.log(e.name); - } - try { - Array(NaN); - } catch (e) { - console.log(e.name); - } - } - expect: { - try { - Function(1, 2); - } catch (e) { - console.log(e.name); - } - try { - RegExp(1, 2); - } catch (e) { - console.log(e.name); - } - try { - Array(NaN); - } catch (e) { - console.log(e.name); - } - } - expect_stdout: [ - "SyntaxError", - "SyntaxError", - "RangeError", - ] -} - collapse_vars_assignment: { options = { collapse_vars: true, @@ -863,23 +662,6 @@ issue_2749: { expect_stdout: "PASS" } -unsafe_builtin: { - options = { - side_effects: true, - unsafe: true, - } - input: { - (!w).constructor(x); - Math.abs(y); - [ 1, 2, z ].valueOf(); - } - expect: { - w, x; - y; - z; - } -} - issue_2860_1: { options = { dead_code: true, @@ -941,24 +723,6 @@ issue_2929: { expect_stdout: "PASS" } -unsafe_string_replace: { - options = { - side_effects: true, - unsafe: true, - } - input: { - "foo".replace("f", function() { - console.log("PASS"); - }); - } - expect: { - "foo".replace("f", function() { - console.log("PASS"); - }); - } - expect_stdout: "PASS" -} - issue_3402: { options = { dead_code: true, diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 15420d8a..b9eea0ed 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -699,18 +699,6 @@ iife: { } } -drop_value: { - options = { - side_effects: true, - } - input: { - (1, [2, foo()], 3, {a:1, b:bar()}); - } - expect: { - foo(), bar(); - } -} - issue_1539: { options = { collapse_vars: true, diff --git a/test/compress/side_effects.js b/test/compress/side_effects.js new file mode 100644 index 00000000..8c263d47 --- /dev/null +++ b/test/compress/side_effects.js @@ -0,0 +1,277 @@ +accessor: { + options = { + side_effects: true, + } + input: { + ({ + get a() {}, + set a(v){ + this.b = 2; + }, + b: 1 + }); + } + expect: {} +} + +issue_2233_1: { + options = { + pure_getters: "strict", + side_effects: true, + unsafe: true, + } + input: { + Array.isArray; + Boolean; + console.log; + Date; + decodeURI; + decodeURIComponent; + encodeURI; + encodeURIComponent; + Error.name; + escape; + eval; + EvalError; + Function.length; + isFinite; + isNaN; + JSON; + Math.random; + Number.isNaN; + parseFloat; + parseInt; + RegExp; + Object.defineProperty; + String.fromCharCode; + RangeError; + ReferenceError; + SyntaxError; + TypeError; + unescape; + URIError; + } + expect: {} + expect_stdout: true +} + +global_timeout_and_interval_symbols: { + options = { + pure_getters: "strict", + side_effects: true, + unsafe: true, + } + input: { + // These global symbols do not exist in the test sandbox + // and must be tested separately. + clearInterval; + clearTimeout; + setInterval; + setTimeout; + } + expect: {} +} + +issue_2233_2: { + options = { + pure_getters: "strict", + reduce_funcs: true, + reduce_vars: true, + side_effects: true, + unsafe: true, + unused: true, + } + input: { + var RegExp; + Array.isArray; + RegExp; + UndeclaredGlobal; + function foo() { + var Number; + AnotherUndeclaredGlobal; + Math.sin; + Number.isNaN; + } + } + expect: { + var RegExp; + UndeclaredGlobal; + function foo() { + var Number; + AnotherUndeclaredGlobal; + Number.isNaN; + } + } +} + +issue_2233_3: { + options = { + pure_getters: "strict", + reduce_funcs: true, + reduce_vars: true, + side_effects: true, + toplevel: true, + unsafe: true, + unused: true, + } + input: { + var RegExp; + Array.isArray; + RegExp; + UndeclaredGlobal; + function foo() { + var Number; + AnotherUndeclaredGlobal; + Math.sin; + Number.isNaN; + } + } + expect: { + UndeclaredGlobal; + } +} + +global_fns: { + options = { + side_effects: true, + unsafe: true, + } + input: { + Boolean(1, 2); + decodeURI(1, 2); + decodeURIComponent(1, 2); + Date(1, 2); + encodeURI(1, 2); + encodeURIComponent(1, 2); + Error(1, 2); + escape(1, 2); + EvalError(1, 2); + isFinite(1, 2); + isNaN(1, 2); + Number(1, 2); + Object(1, 2); + parseFloat(1, 2); + parseInt(1, 2); + RangeError(1, 2); + ReferenceError(1, 2); + String(1, 2); + SyntaxError(1, 2); + TypeError(1, 2); + unescape(1, 2); + URIError(1, 2); + try { + Function(1, 2); + } catch (e) { + console.log(e.name); + } + try { + RegExp(1, 2); + } catch (e) { + console.log(e.name); + } + try { + Array(NaN); + } catch (e) { + console.log(e.name); + } + } + expect: { + try { + Function(1, 2); + } catch (e) { + console.log(e.name); + } + try { + RegExp(1, 2); + } catch (e) { + console.log(e.name); + } + try { + Array(NaN); + } catch (e) { + console.log(e.name); + } + } + expect_stdout: [ + "SyntaxError", + "SyntaxError", + "RangeError", + ] +} + +unsafe_builtin_1: { + options = { + side_effects: true, + unsafe: true, + } + input: { + (!w).constructor(x); + Math.abs(y); + [ 1, 2, z ].valueOf(); + } + expect: { + w, x; + y; + z; + } +} + +unsafe_builtin_2: { + options = { + side_effects: true, + unsafe: true, + } + input: { + var o = {}; + constructor.call(o, 42); + __defineGetter__.call(o, "foo", function() { + return o.p; + }); + __defineSetter__.call(o, void 0, function(a) { + o.p = a; + }); + console.log(typeof o, o.undefined = "PASS", o.foo); + } + expect: { + var o = {}; + constructor.call(o, 42); + __defineGetter__.call(o, "foo", function() { + return o.p; + }); + __defineSetter__.call(o, void 0, function(a) { + o.p = a; + }); + console.log(typeof o, o.undefined = "PASS", o.foo); + } + expect_stdout: "object PASS PASS" +} + +unsafe_string_replace: { + options = { + side_effects: true, + unsafe: true, + } + input: { + "foo".replace("f", function() { + console.log("PASS"); + }); + } + expect: { + "foo".replace("f", function() { + console.log("PASS"); + }); + } + expect_stdout: "PASS" +} + +drop_value: { + options = { + side_effects: true, + } + input: { + (1, [2, foo()], 3, {a:1, b:bar()}); + } + expect: { + foo(), bar(); + } +} |