aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js19
-rw-r--r--test/compress/dead-code.js236
-rw-r--r--test/compress/drop-unused.js12
-rw-r--r--test/compress/side_effects.js277
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();
+ }
+}