aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-04-06 11:18:59 +0800
committerGitHub <noreply@github.com>2017-04-06 11:18:59 +0800
commit06cdb74279d01ed9b4b625200882611482333825 (patch)
tree7d6c5fb4cdedf4bf07ebe88897a887429e76c061 /lib/compress.js
parentff289b90a92739641dcb7fc7f6c8ecf8ee74d15f (diff)
downloadtracifyjs-06cdb74279d01ed9b4b625200882611482333825.tar.gz
tracifyjs-06cdb74279d01ed9b4b625200882611482333825.zip
improve `pure_getters` (#1786)
- property access to `null` & `undefined` always has side effects - utilise `reduce_vars` to determine safe property access - may-be cases treated as side effects unless `unsafe`
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js34
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/compress.js b/lib/compress.js
index ef7f0441..22c79b81 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1160,6 +1160,26 @@ merge(Compressor.prototype, {
&& !node.expression.has_side_effects(compressor);
}
+ (function(def) {
+ def(AST_Node, return_false);
+ def(AST_Null, return_true);
+ def(AST_Undefined, return_true);
+ def(AST_UnaryPrefix, function() {
+ return this.operator == "void";
+ });
+ 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;
+ var fixed = this.fixed_value();
+ return !fixed || fixed.may_eq_null(compressor);
+ });
+ })(function(node, func) {
+ node.DEFMETHOD("may_eq_null", func);
+ });
+
/* -----[ boolean/negation helpers ]----- */
// methods to determine whether an expression has a boolean result type
@@ -1688,7 +1708,7 @@ merge(Compressor.prototype, {
|| this.expression.has_side_effects(compressor);
});
def(AST_SymbolRef, function(compressor){
- return this.global() && this.undeclared();
+ return this.undeclared();
});
def(AST_Object, function(compressor){
return any(this.properties, compressor);
@@ -1701,16 +1721,15 @@ merge(Compressor.prototype, {
});
def(AST_Dot, function(compressor){
if (!compressor.option("pure_getters")) return true;
- return this.expression.has_side_effects(compressor);
+ return this.expression.may_eq_null(compressor)
+ || this.expression.has_side_effects(compressor);
});
def(AST_Sub, function(compressor){
if (!compressor.option("pure_getters")) return true;
- return this.expression.has_side_effects(compressor)
+ return this.expression.may_eq_null(compressor)
+ || this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor);
});
- def(AST_PropAccess, function(compressor){
- return !compressor.option("pure_getters");
- });
def(AST_Seq, function(compressor){
return this.car.has_side_effects(compressor)
|| this.cdr.has_side_effects(compressor);
@@ -2275,10 +2294,12 @@ merge(Compressor.prototype, {
});
def(AST_Dot, function(compressor, first_in_statement){
if (!compressor.option("pure_getters")) return this;
+ if (this.expression.may_eq_null(compressor)) return this;
return this.expression.drop_side_effect_free(compressor, first_in_statement);
});
def(AST_Sub, function(compressor, first_in_statement){
if (!compressor.option("pure_getters")) return this;
+ if (this.expression.may_eq_null(compressor)) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
var property = this.property.drop_side_effect_free(compressor);
@@ -3509,7 +3530,6 @@ merge(Compressor.prototype, {
// testing against !self.scope.uses_with first is an optimization
if (compressor.option("screw_ie8")
&& self.undeclared()
- && !isLHS(self, compressor.parent())
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
switch (self.name) {
case "undefined":