fix pure_getters for chained property access (#1798)

This commit is contained in:
Alex Lam S.L
2017-04-07 17:06:01 +08:00
committed by GitHub
parent e3c9c22c75
commit c2a1bceb77
2 changed files with 36 additions and 24 deletions

View File

@@ -1165,13 +1165,16 @@ merge(Compressor.prototype, {
// may_eq_null() // may_eq_null()
// returns true if this node may evaluate to null or undefined // returns true if this node may evaluate to null or undefined
(function(def) { (function(def) {
function is_strict(compressor) { AST_Node.DEFMETHOD("may_eq_null", function(compressor) {
return /strict/.test(compressor.option("pure_getters")); var pure_getters = compressor.option("pure_getters");
return !pure_getters || this._eq_null(pure_getters);
});
function is_strict(pure_getters) {
return /strict/.test(pure_getters);
} }
def(AST_Node, function(compressor) { def(AST_Node, is_strict);
return !is_strict(compressor);
});
def(AST_Null, return_true); def(AST_Null, return_true);
def(AST_Undefined, return_true); def(AST_Undefined, return_true);
def(AST_Constant, return_false); def(AST_Constant, return_false);
@@ -1182,36 +1185,36 @@ merge(Compressor.prototype, {
def(AST_UnaryPrefix, function() { def(AST_UnaryPrefix, function() {
return this.operator == "void"; return this.operator == "void";
}); });
def(AST_Binary, function(compressor) { def(AST_Binary, function(pure_getters) {
switch (this.operator) { switch (this.operator) {
case "&&": case "&&":
return this.left.may_eq_null(compressor); return this.left._eq_null(pure_getters);
case "||": case "||":
return this.left.may_eq_null(compressor) return this.left._eq_null(pure_getters)
&& this.right.may_eq_null(compressor); && this.right._eq_null(pure_getters);
default: default:
return false; return false;
} }
}) })
def(AST_Assign, function(compressor) { def(AST_Assign, function(pure_getters) {
return this.operator == "=" return this.operator == "="
&& this.right.may_eq_null(compressor); && this.right._eq_null(pure_getters);
}) })
def(AST_Conditional, function(compressor) { def(AST_Conditional, function(pure_getters) {
return this.consequent.may_eq_null(compressor) return this.consequent._eq_null(pure_getters)
|| this.alternative.may_eq_null(compressor); || this.alternative._eq_null(pure_getters);
}) })
def(AST_Seq, function(compressor) { def(AST_Seq, function(pure_getters) {
return this.cdr.may_eq_null(compressor); return this.cdr._eq_null(pure_getters);
}); });
def(AST_SymbolRef, function(compressor) { def(AST_SymbolRef, function(pure_getters) {
if (this.is_undefined) return true; if (this.is_undefined) return true;
if (!is_strict(compressor)) return false; if (!is_strict(pure_getters)) return false;
var fixed = this.fixed_value(); var fixed = this.fixed_value();
return !fixed || fixed.may_eq_null(compressor); return !fixed || fixed._eq_null(pure_getters);
}); });
})(function(node, func) { })(function(node, func) {
node.DEFMETHOD("may_eq_null", func); node.DEFMETHOD("_eq_null", func);
}); });
/* -----[ boolean/negation helpers ]----- */ /* -----[ boolean/negation helpers ]----- */
@@ -1754,12 +1757,10 @@ merge(Compressor.prototype, {
return any(this.elements, compressor); return any(this.elements, compressor);
}); });
def(AST_Dot, function(compressor){ def(AST_Dot, function(compressor){
if (!compressor.option("pure_getters")) return true;
return this.expression.may_eq_null(compressor) return this.expression.may_eq_null(compressor)
|| this.expression.has_side_effects(compressor); || this.expression.has_side_effects(compressor);
}); });
def(AST_Sub, function(compressor){ def(AST_Sub, function(compressor){
if (!compressor.option("pure_getters")) return true;
return this.expression.may_eq_null(compressor) return this.expression.may_eq_null(compressor)
|| this.expression.has_side_effects(compressor) || this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor); || this.property.has_side_effects(compressor);
@@ -2327,12 +2328,10 @@ merge(Compressor.prototype, {
return values && AST_Seq.from_array(values); return values && AST_Seq.from_array(values);
}); });
def(AST_Dot, function(compressor, first_in_statement){ def(AST_Dot, function(compressor, first_in_statement){
if (!compressor.option("pure_getters")) return this;
if (this.expression.may_eq_null(compressor)) return this; if (this.expression.may_eq_null(compressor)) return this;
return this.expression.drop_side_effect_free(compressor, first_in_statement); return this.expression.drop_side_effect_free(compressor, first_in_statement);
}); });
def(AST_Sub, function(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; if (this.expression.may_eq_null(compressor)) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); 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); if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);

View File

@@ -106,3 +106,16 @@ unsafe_reduce_vars: {
(void 0).prop; (void 0).prop;
} }
} }
chained: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
a.b.c;
}
expect: {
a.b.c;
}
}