Compare commits

..

5 Commits

Author SHA1 Message Date
Alex Lam S.L
a7a7b1daed v3.5.2 2019-03-23 14:25:14 +08:00
Alex Lam S.L
7436977aa5 fix infinite loop triggered by #3347 (#3354)
fixes #3353
2019-03-23 14:21:54 +08:00
Alex Lam S.L
e3c565b46f v3.5.1 2019-03-21 13:54:14 +08:00
Alex Lam S.L
54b0b49b68 enhance inline (#3352) 2019-03-21 02:58:33 +08:00
Alex Lam S.L
65648d84a5 enhance collapse_vars (#3351) 2019-03-20 23:31:21 +08:00
4 changed files with 101 additions and 10 deletions

View File

@@ -1361,6 +1361,7 @@ merge(Compressor.prototype, {
hit_stack.push(expr);
if (expr instanceof AST_Assign) {
candidates.push(hit_stack.slice());
extract_candidates(expr.left);
extract_candidates(expr.right);
} else if (expr instanceof AST_Binary) {
extract_candidates(expr.left);
@@ -1376,6 +1377,8 @@ merge(Compressor.prototype, {
extract_candidates(expr.alternative);
} else if (expr instanceof AST_Definitions) {
expr.definitions.forEach(extract_candidates);
} else if (expr instanceof AST_Dot) {
extract_candidates(expr.expression);
} else if (expr instanceof AST_DWLoop) {
extract_candidates(expr.condition);
if (!(expr.body instanceof AST_Block)) {
@@ -1407,6 +1410,9 @@ merge(Compressor.prototype, {
expr.expressions.forEach(extract_candidates);
} else if (expr instanceof AST_SimpleStatement) {
extract_candidates(expr.body);
} else if (expr instanceof AST_Sub) {
extract_candidates(expr.expression);
extract_candidates(expr.property);
} else if (expr instanceof AST_Switch) {
extract_candidates(expr.expression);
expr.body.forEach(extract_candidates);
@@ -1465,6 +1471,7 @@ merge(Compressor.prototype, {
return node;
}
if (parent instanceof AST_IterationStatement) return node;
if (parent instanceof AST_PropAccess) return node;
if (parent instanceof AST_Sequence) {
return find_stop(parent, level + 1, parent.tail_node() !== node);
}
@@ -2239,7 +2246,11 @@ merge(Compressor.prototype, {
});
def(AST_SymbolRef, function() {
var fixed = this.fixed_value();
return fixed && fixed.is_truthy();
if (!fixed) return false;
this.is_truthy = return_false;
var result = fixed.is_truthy();
delete this.is_truthy;
return result;
});
})(function(node, func) {
node.DEFMETHOD("is_truthy", func);
@@ -2293,7 +2304,11 @@ merge(Compressor.prototype, {
if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
if (this.is_immutable()) return false;
var fixed = this.fixed_value();
return !fixed || fixed._dot_throw(compressor);
if (!fixed) return true;
this._dot_throw = return_true;
var result = fixed._dot_throw(compressor);
delete this._dot_throw;
return result;
});
def(AST_UnaryPrefix, function() {
return this.operator == "void";
@@ -2335,7 +2350,11 @@ merge(Compressor.prototype, {
});
def(AST_SymbolRef, function(compressor) {
var fixed = this.fixed_value();
return fixed && fixed.is_boolean(compressor);
if (!fixed) return false;
this.is_boolean = return_false;
var result = fixed.is_boolean(compressor);
delete this.is_boolean;
return result;
});
var unary = makePredicate("! delete");
def(AST_UnaryPrefix, function() {
@@ -2420,7 +2439,11 @@ merge(Compressor.prototype, {
});
def(AST_SymbolRef, function(compressor) {
var fixed = this.fixed_value();
return fixed && fixed.is_number(compressor);
if (!fixed) return false;
this.is_number = return_false;
var result = fixed.is_number(compressor);
delete this.is_number;
return result;
});
var unary = makePredicate("+ - ~ ++ --");
def(AST_Unary, function() {
@@ -2449,7 +2472,11 @@ merge(Compressor.prototype, {
def(AST_String, return_true);
def(AST_SymbolRef, function(compressor) {
var fixed = this.fixed_value();
return fixed && fixed.is_string(compressor);
if (!fixed) return false;
this.is_string = return_false;
var result = fixed.is_string(compressor);
delete this.is_string;
return result;
});
def(AST_UnaryPrefix, function() {
return this.operator == "typeof";
@@ -5065,7 +5092,7 @@ merge(Compressor.prototype, {
}
} while (!(scope instanceof AST_Scope));
var safe_to_inject = (!(scope instanceof AST_Toplevel) || compressor.toplevel.vars)
&& fn.parent_scope === compressor.find_parent(AST_Scope);
&& (exp !== fn || fn.parent_scope === compressor.find_parent(AST_Scope));
var inline = compressor.option("inline");
if (!can_inject_vars(catches, inline >= 3 && safe_to_inject)) return false;
if (!can_inject_args(catches, inline >= 2 && safe_to_inject)) return false;

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.5.0",
"version": "3.5.2",
"engines": {
"node": ">=0.8.0"
},

View File

@@ -3895,11 +3895,11 @@ issue_2436_10: {
o = { b: 3 };
return n;
}
console.log((c = o, [
c.a,
console.log([
(c = o).a,
f(c.b),
c.b,
]).join(" "));
].join(" "));
var c;
}
expect_stdout: "1 2 2"
@@ -6121,3 +6121,39 @@ issue_3327: {
}
expect_stdout: "PASS 42"
}
assign_left: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a, b) {
(b = a, b.p).q = "PASS";
return a.p.q;
}({p: {}}));
}
expect: {
console.log(function(a, b) {
(b = a).p.q = "PASS";
return a.p.q;
}({p: {}}));
}
expect_stdout: "PASS"
}
sub_property: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a, b) {
return a[(b = a, b.length - 1)];
}([ "FAIL", "PASS" ]));
}
expect: {
console.log(function(a, b) {
return a[(b = a).length - 1];
}([ "FAIL", "PASS" ]));
}
expect_stdout: "PASS"
}

View File

@@ -2675,3 +2675,31 @@ cross_references_3: {
"9 27",
]
}
loop_inline: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function(o) {
function g(p) {
return o[p];
}
function h(q) {
while (g(q));
}
return h;
}([ 1, "foo", 0 ])(2));
}
expect: {
console.log(function(o) {
return function(q) {
while (p = q, o[p]);
var p;
};
}([ 1, "foo", 0 ])(2));
}
expect_stdout: "undefined"
}