Support marking a call as pure

A function call or IIFE with an immediately preceding comment
containing `@__PURE__` or `#__PURE__` is deemed to be a
side-effect-free pure function call and can potentially be
dropped.
This commit is contained in:
kzc 2017-01-28 20:37:04 -05:00
parent 7f8d72d9d3
commit 58036cd0cc
2 changed files with 65 additions and 0 deletions

View File

@ -1273,7 +1273,21 @@ merge(Compressor.prototype, {
def(AST_Constant, return_false);
def(AST_This, return_false);
var pure_regex = /[@#]__PURE__/;
function has_pure_annotation(node) {
if (node.pure !== undefined) return node.pure;
var pure = false;
if (node.start
&& node.start.comments_before
&& node.start.comments_before.length
&& pure_regex.test(node.start.comments_before[node.start.comments_before.length - 1].value)) {
pure = true;
}
return node.pure = pure;
}
def(AST_Call, function(compressor){
if (has_pure_annotation(this)) return false;
var pure = compressor.option("pure_funcs");
if (!pure) return true;
if (typeof pure == "function") return pure(this);

View File

@ -0,0 +1,51 @@
pure_function_calls: {
options = {
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
negate_iife : true,
}
input: {
// pure top-level IIFE will be dropped
// @__PURE__ - comment
(function() {
console.log("iife0");
})();
// pure top-level IIFE assigned to unreferenced var will not be dropped
var iife1 = /*@__PURE__*/(function() {
console.log("iife1");
function iife1() {}
return iife1;
})();
(function(){
// pure IIFE in function scope assigned to unreferenced var will be dropped
var iife2 = /*#__PURE__*/(function() {
console.log("iife2");
function iife2() {}
return iife2;
})();
})();
// comment #__PURE__ comment
bar(), baz(), quux();
a.b(), /* @__PURE__ */ c.d.e(), f.g();
}
expect: {
var iife1 = function() {
console.log("iife1");
function iife1() {}
return iife1;
}();
baz(), quux();
a.b(), f.g();
}
}