From e3d99ef1e06a7c4fff55a0dd77f2aa1610f8968d Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Sun, 24 Dec 2017 03:00:58 +0800 Subject: [PATCH] improve `/*@__PURE__*/` fixes #2638 --- lib/compress.js | 20 ++--------------- lib/parse.js | 20 +++++++++++++++-- test/compress/pure_funcs.js | 45 ++++++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 6b2c936a..1c052dd2 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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))) { diff --git a/lib/parse.js b/lib/parse.js index 41aa988b..cdf3fdc1 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -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; }; diff --git a/test/compress/pure_funcs.js b/test/compress/pure_funcs.js index 6f3bbb21..1231e508 100644 --- a/test/compress/pure_funcs.js +++ b/test/compress/pure_funcs.js @@ -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: {