aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js31
-rw-r--r--test/compress/collapse_vars.js76
2 files changed, 93 insertions, 14 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 2d0a03ae..c402e3ba 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -913,8 +913,8 @@ merge(Compressor.prototype, {
}
function tighten_body(statements, compressor) {
- var scope = compressor.find_parent(AST_Scope);
- var in_loop = is_in_node(AST_IterationStatement);
+ var in_loop, in_try, scope;
+ find_loop_scope_try();
var CHANGED, max_iter = 10;
do {
CHANGED = false;
@@ -937,13 +937,20 @@ merge(Compressor.prototype, {
}
} while (CHANGED && max_iter-- > 0);
- function is_in_node(type) {
- if (compressor.self() instanceof type) return true;
- for (var node, level = 0; node = compressor.parent(level); level++) {
- if (node instanceof type) return true;
- if (node instanceof AST_Scope) break;
- }
- return false;
+ function find_loop_scope_try() {
+ var node = compressor.self(), level = 0;
+ do {
+ if (node instanceof AST_Catch || node instanceof AST_Finally) {
+ level++;
+ } else if (node instanceof AST_IterationStatement) {
+ 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:
@@ -958,7 +965,6 @@ merge(Compressor.prototype, {
if (scope.uses_eval || scope.uses_with) return statements;
var args;
var candidates = [];
- var in_try = is_in_node(AST_Try);
var stat_index = statements.length;
var scanner = new TreeTransformer(function(node, descend) {
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.scope !== scope) return true;
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;
});
}
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index ecf64241..60505509 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -2219,8 +2219,8 @@ unused_orig: {
console.log(function(b) {
var c = b;
for (var d in c) {
- var a = c[0];
- return --b + a;
+ var a;
+ return --b + c[0];
}
a && a.NaN;
}([2]), a);
@@ -4666,7 +4666,7 @@ issue_2931: {
expect_stdout: "undefined"
}
-issue_2954: {
+issue_2954_1: {
options = {
collapse_vars: true,
}
@@ -4700,3 +4700,73 @@ issue_2954: {
}
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")
+}