compress AST_Arrow properly (#2170)
This commit is contained in:
@@ -366,7 +366,7 @@ merge(Compressor.prototype, {
|
|||||||
safe_ids = save_ids;
|
safe_ids = save_ids;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Function || node instanceof AST_Arrow) {
|
if (is_func_expr(node)) {
|
||||||
push();
|
push();
|
||||||
var iife;
|
var iife;
|
||||||
if (!node.name
|
if (!node.name
|
||||||
@@ -564,6 +564,10 @@ merge(Compressor.prototype, {
|
|||||||
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function is_func_expr(node) {
|
||||||
|
return node instanceof AST_Arrow || node instanceof AST_Function;
|
||||||
|
}
|
||||||
|
|
||||||
function is_lhs_read_only(lhs) {
|
function is_lhs_read_only(lhs) {
|
||||||
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
||||||
if (lhs instanceof AST_PropAccess) {
|
if (lhs instanceof AST_PropAccess) {
|
||||||
@@ -707,7 +711,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function is_iife_call(node) {
|
function is_iife_call(node) {
|
||||||
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
||||||
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
return is_func_expr(node.expression) || is_iife_call(node.expression);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1324,7 @@ merge(Compressor.prototype, {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
def(AST_Function, return_false);
|
def(AST_Function, return_false);
|
||||||
|
def(AST_Arrow, return_false);
|
||||||
def(AST_UnaryPostfix, return_false);
|
def(AST_UnaryPostfix, return_false);
|
||||||
def(AST_UnaryPrefix, function() {
|
def(AST_UnaryPrefix, function() {
|
||||||
return this.operator == "void";
|
return this.operator == "void";
|
||||||
@@ -1593,9 +1598,6 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Lambda, function(){
|
def(AST_Lambda, function(){
|
||||||
throw def;
|
throw def;
|
||||||
});
|
});
|
||||||
def(AST_Arrow, function() {
|
|
||||||
throw def;
|
|
||||||
});
|
|
||||||
def(AST_Class, function() {
|
def(AST_Class, function() {
|
||||||
throw def;
|
throw def;
|
||||||
});
|
});
|
||||||
@@ -1649,8 +1651,7 @@ merge(Compressor.prototype, {
|
|||||||
case "typeof":
|
case "typeof":
|
||||||
// Function would be evaluated to an array and so typeof would
|
// Function would be evaluated to an array and so typeof would
|
||||||
// incorrectly return 'object'. Hence making is a special case.
|
// incorrectly return 'object'. Hence making is a special case.
|
||||||
if (e instanceof AST_Function ||
|
if (is_func_expr(e)) return typeof function(){};
|
||||||
e instanceof AST_Arrow) return typeof function(){};
|
|
||||||
|
|
||||||
e = ev(e, compressor);
|
e = ev(e, compressor);
|
||||||
|
|
||||||
@@ -1822,6 +1823,9 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Function, function(){
|
def(AST_Function, function(){
|
||||||
return basic_negation(this);
|
return basic_negation(this);
|
||||||
});
|
});
|
||||||
|
def(AST_Arrow, function(){
|
||||||
|
return basic_negation(this);
|
||||||
|
});
|
||||||
def(AST_UnaryPrefix, function(){
|
def(AST_UnaryPrefix, function(){
|
||||||
if (this.operator == "!")
|
if (this.operator == "!")
|
||||||
return this.expression;
|
return this.expression;
|
||||||
@@ -2568,7 +2572,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_This, return_null);
|
def(AST_This, return_null);
|
||||||
def(AST_Call, function(compressor, first_in_statement){
|
def(AST_Call, function(compressor, first_in_statement){
|
||||||
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
||||||
if (this.expression instanceof AST_Function
|
if (is_func_expr(this.expression)
|
||||||
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
node.expression.process_expression(false, compressor);
|
node.expression.process_expression(false, compressor);
|
||||||
@@ -3095,10 +3099,10 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& simple_args
|
&& simple_args
|
||||||
&& (fn instanceof AST_Function
|
&& (is_func_expr(fn)
|
||||||
|| compressor.option("reduce_vars")
|
|| compressor.option("reduce_vars")
|
||||||
&& fn instanceof AST_SymbolRef
|
&& fn instanceof AST_SymbolRef
|
||||||
&& (fn = fn.fixed_value()) instanceof AST_Function)
|
&& is_func_expr(fn = fn.fixed_value()))
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.uses_eval) {
|
&& !fn.uses_eval) {
|
||||||
var pos = 0, last = 0;
|
var pos = 0, last = 0;
|
||||||
@@ -3272,7 +3276,7 @@ merge(Compressor.prototype, {
|
|||||||
if (self.args.length == 0) return make_node(AST_Function, self, {
|
if (self.args.length == 0) return make_node(AST_Function, self, {
|
||||||
argnames: [],
|
argnames: [],
|
||||||
body: []
|
body: []
|
||||||
});
|
}).optimize(compressor);
|
||||||
if (all(self.args, function(x) {
|
if (all(self.args, function(x) {
|
||||||
return x instanceof AST_String;
|
return x instanceof AST_String;
|
||||||
})) {
|
})) {
|
||||||
@@ -3295,12 +3299,18 @@ merge(Compressor.prototype, {
|
|||||||
var fun;
|
var fun;
|
||||||
ast.walk(new TreeWalker(function(node) {
|
ast.walk(new TreeWalker(function(node) {
|
||||||
if (fun) return true;
|
if (fun) return true;
|
||||||
if (node instanceof AST_Function) {
|
if (is_func_expr(node)) {
|
||||||
fun = node;
|
fun = node;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
if (!fun) return self;
|
if (fun.body instanceof AST_Node) {
|
||||||
|
fun.body = [
|
||||||
|
make_node(AST_Return, fun.body, {
|
||||||
|
value: fun.body
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
var args = fun.argnames.map(function(arg, i) {
|
var args = fun.argnames.map(function(arg, i) {
|
||||||
return make_node(AST_String, self.args[i], {
|
return make_node(AST_String, self.args[i], {
|
||||||
value: arg.print_to_string()
|
value: arg.print_to_string()
|
||||||
@@ -3324,7 +3334,14 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stat = fn instanceof AST_Function && fn.body[0];
|
var stat = is_func_expr(fn) && fn.body;
|
||||||
|
if (stat instanceof AST_Node) {
|
||||||
|
stat = make_node(AST_Return, stat, {
|
||||||
|
value: stat
|
||||||
|
});
|
||||||
|
} else if (stat) {
|
||||||
|
stat = stat[0];
|
||||||
|
}
|
||||||
if (compressor.option("inline") && stat instanceof AST_Return) {
|
if (compressor.option("inline") && stat instanceof AST_Return) {
|
||||||
var value = stat.value;
|
var value = stat.value;
|
||||||
if (!value || value.is_constant_expression()) {
|
if (!value || value.is_constant_expression()) {
|
||||||
@@ -3332,10 +3349,10 @@ merge(Compressor.prototype, {
|
|||||||
return make_sequence(self, args).transform(compressor);
|
return make_sequence(self, args).transform(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exp instanceof AST_Function && !exp.is_generator && !exp.async) {
|
if (is_func_expr(exp) && !exp.is_generator && !exp.async) {
|
||||||
if (compressor.option("inline")
|
if (compressor.option("inline")
|
||||||
&& !exp.name
|
&& !exp.name
|
||||||
&& exp.body.length == 1
|
&& (exp.body instanceof AST_Node || exp.body.length == 1)
|
||||||
&& !exp.uses_arguments
|
&& !exp.uses_arguments
|
||||||
&& !exp.uses_eval
|
&& !exp.uses_eval
|
||||||
&& simple_args
|
&& simple_args
|
||||||
@@ -3385,6 +3402,13 @@ merge(Compressor.prototype, {
|
|||||||
value: value
|
value: value
|
||||||
}));
|
}));
|
||||||
var body = fn.transform(compressor).body;
|
var body = fn.transform(compressor).body;
|
||||||
|
if (body instanceof AST_Node) {
|
||||||
|
body = [
|
||||||
|
make_node(AST_Return, body, {
|
||||||
|
value: body
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
if (body.length == 0) return make_node(AST_Undefined, self);
|
if (body.length == 0) return make_node(AST_Undefined, self);
|
||||||
if (body.length == 1 && body[0] instanceof AST_Return) {
|
if (body.length == 1 && body[0] instanceof AST_Return) {
|
||||||
value = body[0].value;
|
value = body[0].value;
|
||||||
@@ -3411,7 +3435,7 @@ merge(Compressor.prototype, {
|
|||||||
if (value !== self) return value;
|
if (value !== self) return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects") && all(exp.body, is_empty)) {
|
if (compressor.option("side_effects") && !(exp.body instanceof AST_Node) && all(exp.body, is_empty)) {
|
||||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||||
return make_sequence(self, args).transform(compressor);
|
return make_sequence(self, args).transform(compressor);
|
||||||
}
|
}
|
||||||
@@ -4085,7 +4109,7 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
||||||
}
|
}
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& fixed instanceof AST_Function
|
&& is_func_expr(fixed)
|
||||||
&& d.references.length == 1
|
&& d.references.length == 1
|
||||||
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
||||||
&& !d.scope.uses_eval
|
&& !d.scope.uses_eval
|
||||||
|
|||||||
@@ -280,3 +280,261 @@ issue_27: {
|
|||||||
})(jQuery);
|
})(jQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2105_1: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(factory) {
|
||||||
|
factory();
|
||||||
|
}( function() {
|
||||||
|
return function(fn) {
|
||||||
|
fn()().prop();
|
||||||
|
}( function() {
|
||||||
|
function bar() {
|
||||||
|
var quux = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = function() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
}
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!void (() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2105_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
((factory) => {
|
||||||
|
factory();
|
||||||
|
})( () => {
|
||||||
|
return ((fn) => {
|
||||||
|
fn()().prop();
|
||||||
|
})( () => {
|
||||||
|
let bar = () => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!void (() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_2: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
f([2,3][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_3: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(1, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args_drop_param: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(b, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_485_crashing_1530: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
if (true) return;
|
||||||
|
var b = 42;
|
||||||
|
})(this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
this, void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2084: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function() {
|
||||||
|
!function(c) {
|
||||||
|
c = 1 + c;
|
||||||
|
var c = 0;
|
||||||
|
function f14(a_1) {
|
||||||
|
if (c = 1 + c, 0 !== 23..toString())
|
||||||
|
c = 1 + c, a_1 && (a_1[0] = 0);
|
||||||
|
}
|
||||||
|
f14();
|
||||||
|
}(-1);
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
!((c) => {
|
||||||
|
c = 1 + c,
|
||||||
|
c = 1 + (c = 0),
|
||||||
|
0 !== 23..toString() && (c = 1 + c);
|
||||||
|
})(-1),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ compress_new_function_with_destruct_arrows: {
|
|||||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("aa, [bb]", 'return aa;');
|
Function("N", "[a]", 'return N');
|
||||||
Function("aa, {bb}", 'return aa;');
|
Function("b", "{bb:N}", 'return b');
|
||||||
Function("[[aa]], [{bb}]", 'return aa;');
|
Function("[[b]]", "[{bb:N}]", 'return b');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user