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"); 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) { AST_Call.DEFMETHOD("is_expr_pure", function(compressor) {
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
var expr = this.expression; var expr = this.expression;
if (is_undeclared_ref(expr) && global_pure_fns(expr.name)) return true; 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 // determine if expression has side effects
@ -3961,7 +3945,7 @@ merge(Compressor.prototype, {
&& (def = exp.definition()).references.length == 1 && (def = exp.definition()).references.length == 1
&& !recursive_ref(compressor, def) && !recursive_ref(compressor, def)
&& fn.is_constant_expression(exp.scope)) && fn.is_constant_expression(exp.scope))
&& !self.has_pure_annotation(compressor) && !self.pure
&& !fn.contains_this() && !fn.contains_this()
&& (scope = can_flatten_args(fn)) && (scope = can_flatten_args(fn))
&& (value = flatten_body(stat))) { && (value = flatten_body(stat))) {

View File

@ -1276,6 +1276,7 @@ function parse($TEXT, options) {
case "(": case "(":
next(); next();
var ex = expression(true); var ex = expression(true);
start.comments_before.orig_len = start.comments_before.length;
[].push.apply(start.comments_before, ex.start.comments_before); [].push.apply(start.comments_before, ex.start.comments_before);
ex.start.comments_before = start.comments_before; ex.start.comments_before = start.comments_before;
start.comments_after = ex.start.comments_after; start.comments_after = ex.start.comments_after;
@ -1286,6 +1287,7 @@ function parse($TEXT, options) {
[].push.apply(ex.end.comments_after, end.comments_after); [].push.apply(ex.end.comments_after, end.comments_after);
end.comments_after = ex.end.comments_after; end.comments_after = ex.end.comments_after;
ex.end = end; ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex);
return subscripts(ex, allow_calls); return subscripts(ex, allow_calls);
case "[": case "[":
return subscripts(array_(), allow_calls); return subscripts(array_(), allow_calls);
@ -1433,6 +1435,18 @@ function parse($TEXT, options) {
return sym; 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 subscripts = function(expr, allow_calls) {
var start = expr.start; var start = expr.start;
if (is("punc", ".")) { if (is("punc", ".")) {
@ -1457,12 +1471,14 @@ function parse($TEXT, options) {
} }
if (allow_calls && is("punc", "(")) { if (allow_calls && is("punc", "(")) {
next(); next();
return subscripts(new AST_Call({ var call = new AST_Call({
start : start, start : start,
expression : expr, expression : expr,
args : expr_list(")"), args : expr_list(")"),
end : prev() end : prev()
}), true); });
mark_pure(call);
return subscripts(call, true);
} }
return expr; return expr;
}; };

View File

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