@@ -913,8 +913,8 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function tighten_body(statements, compressor) {
|
function tighten_body(statements, compressor) {
|
||||||
var scope = compressor.find_parent(AST_Scope);
|
var in_loop, in_try, scope;
|
||||||
var in_loop = is_in_node(AST_IterationStatement);
|
find_loop_scope_try();
|
||||||
var CHANGED, max_iter = 10;
|
var CHANGED, max_iter = 10;
|
||||||
do {
|
do {
|
||||||
CHANGED = false;
|
CHANGED = false;
|
||||||
@@ -937,13 +937,20 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
} while (CHANGED && max_iter-- > 0);
|
} while (CHANGED && max_iter-- > 0);
|
||||||
|
|
||||||
function is_in_node(type) {
|
function find_loop_scope_try() {
|
||||||
if (compressor.self() instanceof type) return true;
|
var node = compressor.self(), level = 0;
|
||||||
for (var node, level = 0; node = compressor.parent(level); level++) {
|
do {
|
||||||
if (node instanceof type) return true;
|
if (node instanceof AST_Catch || node instanceof AST_Finally) {
|
||||||
if (node instanceof AST_Scope) break;
|
level++;
|
||||||
}
|
} else if (node instanceof AST_IterationStatement) {
|
||||||
return false;
|
in_loop = true;
|
||||||
|
} else if (node instanceof AST_Scope) {
|
||||||
|
scope = node;
|
||||||
|
break;
|
||||||
|
} else if (node instanceof AST_Try) {
|
||||||
|
in_try = true;
|
||||||
|
}
|
||||||
|
} while (node = compressor.parent(level++));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search from right to left for assignment-like expressions:
|
// Search from right to left for assignment-like expressions:
|
||||||
@@ -958,7 +965,6 @@ merge(Compressor.prototype, {
|
|||||||
if (scope.uses_eval || scope.uses_with) return statements;
|
if (scope.uses_eval || scope.uses_with) return statements;
|
||||||
var args;
|
var args;
|
||||||
var candidates = [];
|
var candidates = [];
|
||||||
var in_try = is_in_node(AST_Try);
|
|
||||||
var stat_index = statements.length;
|
var stat_index = statements.length;
|
||||||
var scanner = new TreeTransformer(function(node, descend) {
|
var scanner = new TreeTransformer(function(node, descend) {
|
||||||
if (abort) return node;
|
if (abort) return node;
|
||||||
@@ -1433,7 +1439,10 @@ merge(Compressor.prototype, {
|
|||||||
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;
|
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;
|
||||||
if (def.scope !== scope) return true;
|
if (def.scope !== scope) return true;
|
||||||
return !all(def.references, function(ref) {
|
return !all(def.references, function(ref) {
|
||||||
return ref.scope === scope;
|
var s = ref.scope;
|
||||||
|
// "block" scope within AST_Catch
|
||||||
|
if (s.TYPE == "Scope") s = s.parent_scope;
|
||||||
|
return s === scope;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2219,8 +2219,8 @@ unused_orig: {
|
|||||||
console.log(function(b) {
|
console.log(function(b) {
|
||||||
var c = b;
|
var c = b;
|
||||||
for (var d in c) {
|
for (var d in c) {
|
||||||
var a = c[0];
|
var a;
|
||||||
return --b + a;
|
return --b + c[0];
|
||||||
}
|
}
|
||||||
a && a.NaN;
|
a && a.NaN;
|
||||||
}([2]), a);
|
}([2]), a);
|
||||||
@@ -4666,7 +4666,7 @@ issue_2931: {
|
|||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2954: {
|
issue_2954_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
}
|
}
|
||||||
@@ -4700,3 +4700,73 @@ issue_2954: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2954_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL_1", b;
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (e) {
|
||||||
|
do {
|
||||||
|
b = function() {
|
||||||
|
throw new Error("PASS");
|
||||||
|
}();
|
||||||
|
a = "FAIL_2";
|
||||||
|
b && b.c;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL_1", b;
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (e) {
|
||||||
|
do {
|
||||||
|
a = "FAIL_2";
|
||||||
|
(b = function() {
|
||||||
|
throw new Error("PASS");
|
||||||
|
}()) && b.c;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: Error("PASS")
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2954_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL_1", b;
|
||||||
|
try {
|
||||||
|
} finally {
|
||||||
|
do {
|
||||||
|
b = function() {
|
||||||
|
throw new Error("PASS");
|
||||||
|
}();
|
||||||
|
a = "FAIL_2";
|
||||||
|
b && b.c;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL_1", b;
|
||||||
|
try {
|
||||||
|
} finally {
|
||||||
|
do {
|
||||||
|
a = "FAIL_2";
|
||||||
|
(b = function() {
|
||||||
|
throw new Error("PASS");
|
||||||
|
}()) && b.c;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: Error("PASS")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user