aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-04-07 13:31:58 +0800
committerGitHub <noreply@github.com>2017-04-07 13:31:58 +0800
commit0f4cd73dcc5d8a936ae3630a7992dbcb44274136 (patch)
tree3c5724a3ef73c80868849800630c92d57d28b806
parent281e882d27ace48c5c415f19292e2590dd4473dc (diff)
downloadtracifyjs-0f4cd73dcc5d8a936ae3630a7992dbcb44274136.tar.gz
tracifyjs-0f4cd73dcc5d8a936ae3630a7992dbcb44274136.zip
introduce "strict" to `pure_getters` (#1795)
-rw-r--r--README.md2
-rw-r--r--lib/compress.js15
-rw-r--r--test/compress/pure_getters.js39
-rw-r--r--test/compress/reduce_vars.js19
4 files changed, 59 insertions, 16 deletions
diff --git a/README.md b/README.md
index d57a15ce..d15f114c 100644
--- a/README.md
+++ b/README.md
@@ -411,6 +411,8 @@ to set `true`; it's effectively a shortcut for `foo=true`).
- `pure_getters` -- the default is `false`. If you pass `true` for
this, UglifyJS will assume that object property access
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
+ Specify `"strict"` to treat `foo.bar` as side-effect-free only when
+ `foo` is certain to not throw, i.e. not `null` or `undefined`.
- `pure_funcs` -- default `null`. You can pass an array of names and
UglifyJS will assume that those functions do not produce side
diff --git a/lib/compress.js b/lib/compress.js
index 8df6e58f..c199d13f 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -71,7 +71,7 @@ function Compressor(options, false_by_default) {
negate_iife : !false_by_default,
passes : 1,
properties : !false_by_default,
- pure_getters : false,
+ pure_getters : !false_by_default && "strict",
pure_funcs : null,
reduce_vars : !false_by_default,
screw_ie8 : true,
@@ -1165,7 +1165,13 @@ merge(Compressor.prototype, {
// may_eq_null()
// returns true if this node may evaluate to null or undefined
(function(def) {
- def(AST_Node, return_true);
+ function is_strict(compressor) {
+ return /strict/.test(compressor.option("pure_getters"));
+ }
+
+ def(AST_Node, function(compressor) {
+ return !is_strict(compressor);
+ });
def(AST_Null, return_true);
def(AST_Undefined, return_true);
def(AST_Constant, return_false);
@@ -1198,12 +1204,9 @@ merge(Compressor.prototype, {
def(AST_Seq, function(compressor) {
return this.cdr.may_eq_null(compressor);
});
- def(AST_PropAccess, function(compressor) {
- return !compressor.option("unsafe");
- });
def(AST_SymbolRef, function(compressor) {
if (this.is_undefined) return true;
- if (compressor.option("unsafe")) return false;
+ if (!is_strict(compressor)) return false;
var fixed = this.fixed_value();
return !fixed || fixed.may_eq_null(compressor);
});
diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js
index 338f8639..c2dcb95b 100644
--- a/test/compress/pure_getters.js
+++ b/test/compress/pure_getters.js
@@ -1,10 +1,9 @@
-side_effects: {
+strict: {
options = {
- pure_getters: true,
+ pure_getters: "strict",
reduce_vars: false,
side_effects: true,
toplevel: true,
- unsafe: false,
}
input: {
var a, b = null, c = {};
@@ -28,13 +27,12 @@ side_effects: {
}
}
-side_effects_reduce_vars: {
+strict_reduce_vars: {
options = {
- pure_getters: true,
+ pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
- unsafe: false,
}
input: {
var a, b = null, c = {};
@@ -57,13 +55,38 @@ side_effects_reduce_vars: {
}
}
-side_effects_unsafe: {
+unsafe: {
options = {
pure_getters: true,
reduce_vars: false,
side_effects: true,
toplevel: true,
- unsafe: true,
+ }
+ input: {
+ var a, b = null, c = {};
+ a.prop;
+ b.prop;
+ c.prop;
+ d.prop;
+ null.prop;
+ (void 0).prop;
+ undefined.prop;
+ }
+ expect: {
+ var a, b = null, c = {};
+ d;
+ null.prop;
+ (void 0).prop;
+ (void 0).prop;
+ }
+}
+
+unsafe_reduce_vars: {
+ options = {
+ pure_getters: true,
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
}
input: {
var a, b = null, c = {};
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 842d8de4..b6f711ad 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1919,7 +1919,7 @@ side_effects_assign: {
pure_getters_1: {
options = {
- pure_getters: true,
+ pure_getters: "strict",
reduce_vars: true,
side_effects: true,
toplevel: true,
@@ -1941,7 +1941,7 @@ pure_getters_1: {
pure_getters_2: {
options = {
- pure_getters: true,
+ pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
@@ -1956,6 +1956,21 @@ pure_getters_2: {
}
}
+pure_getters_3: {
+ options = {
+ pure_getters: true,
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a;
+ var a = a && a.b;
+ }
+ expect: {
+ }
+}
+
catch_var: {
options = {
booleans: true,