improve /*@__PURE__*/

fixes #2638
This commit is contained in:
alexlamsl 2017-12-24 03:00:58 +08:00
parent 202f90ef8f
commit e3d99ef1e0
3 changed files with 49 additions and 36 deletions

View File

@ -2292,29 +2292,13 @@ merge(Compressor.prototype, {
});
});
AST_Call.DEFMETHOD("has_pure_annotation", function(compressor) {
if (!compressor.option("side_effects")) return false;
if (this.pure !== undefined) return this.pure;
var pure = false;
var comments, pure_comment;
if (this.start
&& (comments = this.start.comments_before)
&& comments.length
&& (pure_comment = find_if(function (comment) {
return /[@#]__PURE__/.test(comment.value);
}, comments))) {
pure = pure_comment;
}
return this.pure = pure;
});
var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
AST_Call.DEFMETHOD("is_expr_pure", function(compressor) {
if (compressor.option("unsafe")) {
var expr = this.expression;
if (is_undeclared_ref(expr) && global_pure_fns(expr.name)) return true;
}
return this.has_pure_annotation(compressor) || !compressor.pure_funcs(this);
return this.pure || !compressor.pure_funcs(this);
});
// determine if expression has side effects
@ -3961,7 +3945,7 @@ merge(Compressor.prototype, {
&& (def = exp.definition()).references.length == 1
&& !recursive_ref(compressor, def)
&& fn.is_constant_expression(exp.scope))
&& !self.has_pure_annotation(compressor)
&& !self.pure
&& !fn.contains_this()
&& (scope = can_flatten_args(fn))
&& (value = flatten_body(stat))) {

View File

@ -1276,6 +1276,7 @@ function parse($TEXT, options) {
case "(":
next();
var ex = expression(true);
start.comments_before.orig_len = start.comments_before.length;
[].push.apply(start.comments_before, ex.start.comments_before);
ex.start.comments_before = start.comments_before;
start.comments_after = ex.start.comments_after;
@ -1286,6 +1287,7 @@ function parse($TEXT, options) {
[].push.apply(ex.end.comments_after, end.comments_after);
end.comments_after = ex.end.comments_after;
ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex);
return subscripts(ex, allow_calls);
case "[":
return subscripts(array_(), allow_calls);
@ -1433,6 +1435,18 @@ function parse($TEXT, options) {
return sym;
};
function mark_pure(call) {
var comments = call.start.comments_before;
var i = HOP(comments, "orig_len") ? comments.orig_len : comments.length;
while (--i >= 0) {
var comment = comments[i];
if (/[@#]__PURE__/.test(comment.value)) {
call.pure = comment;
break;
}
}
}
var subscripts = function(expr, allow_calls) {
var start = expr.start;
if (is("punc", ".")) {
@ -1457,12 +1471,14 @@ function parse($TEXT, options) {
}
if (allow_calls && is("punc", "(")) {
next();
return subscripts(new AST_Call({
var call = new AST_Call({
start : start,
expression : expr,
args : expr_list(")"),
end : prev()
}), true);
});
mark_pure(call);
return subscripts(call, true);
}
return expr;
};

View File

@ -304,7 +304,9 @@ issue_2629_1: {
(/*@__PURE__*/ c)();
(/*@__PURE__*/ d());
}
expect: {}
expect: {
(/*@__PURE__*/ c)();
}
}
issue_2629_2: {
@ -321,7 +323,11 @@ issue_2629_2: {
(/*@__PURE__*/ g(1)(2))(3);
(/*@__PURE__*/ h(1)(2)(3));
}
expect: {}
expect: {
(/*@__PURE__*/ e)(1)(2)(3);
(/*@__PURE__*/ f(1))(2)(3);
(/*@__PURE__*/ g(1)(2))(3);
}
}
issue_2629_3: {
@ -330,21 +336,28 @@ issue_2629_3: {
}
input: {
/*@__PURE__*/ a.x(1).y(2).z(3);
/*@__PURE__*/ (a.x)(1).y(2).z(3);
/*@__PURE__*/ (a.x(1)).y(2).z(3);
/*@__PURE__*/ (a.x(1).y)(2).z(3);
/*@__PURE__*/ (a.x(1).y(2)).z(3);
/*@__PURE__*/ (a.x(1).y(2).z)(3);
/*@__PURE__*/ (a.x(1).y(2).z(3));
(/*@__PURE__*/ a).x(1).y(2).z(3);
(/*@__PURE__*/ a.x)(1).y(2).z(3);
(/*@__PURE__*/ a.x(1)).y(2).z(3);
(/*@__PURE__*/ a.x(1).y)(2).z(3);
(/*@__PURE__*/ a.x(1).y(2)).z(3);
(/*@__PURE__*/ a.x(1).y(2).z)(3);
(/*@__PURE__*/ a.x(1).y(2).z(3));
/*@__PURE__*/ (b.x)(1).y(2).z(3);
/*@__PURE__*/ (c.x(1)).y(2).z(3);
/*@__PURE__*/ (d.x(1).y)(2).z(3);
/*@__PURE__*/ (e.x(1).y(2)).z(3);
/*@__PURE__*/ (f.x(1).y(2).z)(3);
/*@__PURE__*/ (g.x(1).y(2).z(3));
(/*@__PURE__*/ h).x(1).y(2).z(3);
(/*@__PURE__*/ i.x)(1).y(2).z(3);
(/*@__PURE__*/ j.x(1)).y(2).z(3);
(/*@__PURE__*/ k.x(1).y)(2).z(3);
(/*@__PURE__*/ l.x(1).y(2)).z(3);
(/*@__PURE__*/ m.x(1).y(2).z)(3);
(/*@__PURE__*/ n.x(1).y(2).z(3));
}
expect: {
(/*@__PURE__*/ h).x(1).y(2).z(3);
(/*@__PURE__*/ i.x)(1).y(2).z(3);
(/*@__PURE__*/ j.x(1)).y(2).z(3);
(/*@__PURE__*/ k.x(1).y)(2).z(3);
(/*@__PURE__*/ l.x(1).y(2)).z(3);
(/*@__PURE__*/ m.x(1).y(2).z)(3);
}
expect: {}
}
issue_2629_4: {