Skip to content

Commit 48ffbef

Browse files
authored
account for cross-scope modifications in collapse_vars (#1634)
mostly done by @kzc fixes #1631
1 parent c0f3fea commit 48ffbef

File tree

3 files changed

+121
-2
lines changed

3 files changed

+121
-2
lines changed

lib/compress.js

+12
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,24 @@ merge(Compressor.prototype, {
619619
|| node instanceof AST_IterationStatement
620620
|| (parent instanceof AST_If && node !== parent.condition)
621621
|| (parent instanceof AST_Conditional && node !== parent.condition)
622+
|| (node instanceof AST_SymbolRef
623+
&& !are_references_in_scope(node.definition(), self))
622624
|| (parent instanceof AST_Binary
623625
&& (parent.operator == "&&" || parent.operator == "||")
624626
&& node === parent.right)
625627
|| (parent instanceof AST_Switch && node !== parent.expression)) {
626628
return side_effects_encountered = unwind = true, node;
627629
}
630+
function are_references_in_scope(def, scope) {
631+
if (def.orig.length === 1
632+
&& def.orig[0] instanceof AST_SymbolDefun) return true;
633+
if (def.scope !== scope) return false;
634+
var refs = def.references;
635+
for (var i = 0, len = refs.length; i < len; i++) {
636+
if (refs[i].scope !== scope) return false;
637+
}
638+
return true;
639+
}
628640
},
629641
function postorder(node) {
630642
if (unwind) return node;

test/compress/collapse_vars.js

+107
Original file line numberDiff line numberDiff line change
@@ -1415,3 +1415,110 @@ issue_1605_2: {
14151415
(new Object).p = 1;
14161416
}
14171417
}
1418+
1419+
issue_1631_1: {
1420+
options = {
1421+
cascade: true,
1422+
collapse_vars: true,
1423+
hoist_funs: true,
1424+
join_vars: true,
1425+
sequences: true,
1426+
side_effects: true,
1427+
}
1428+
input: {
1429+
var pc = 0;
1430+
function f(x) {
1431+
pc = 200;
1432+
return 100;
1433+
}
1434+
function x() {
1435+
var t = f();
1436+
pc += t;
1437+
return pc;
1438+
}
1439+
console.log(x());
1440+
}
1441+
expect: {
1442+
function f(x) {
1443+
return pc = 200, 100;
1444+
}
1445+
function x() {
1446+
var t = f();
1447+
return pc += t;
1448+
}
1449+
var pc = 0;
1450+
console.log(x());
1451+
}
1452+
expect_stdout: "300"
1453+
}
1454+
1455+
issue_1631_2: {
1456+
options = {
1457+
cascade: true,
1458+
collapse_vars: true,
1459+
hoist_funs: true,
1460+
join_vars: true,
1461+
sequences: true,
1462+
side_effects: true,
1463+
}
1464+
input: {
1465+
var a = 0, b = 1;
1466+
function f() {
1467+
a = 2;
1468+
return 4;
1469+
}
1470+
function g() {
1471+
var t = f();
1472+
b = a + t;
1473+
return b;
1474+
}
1475+
console.log(g());
1476+
}
1477+
expect: {
1478+
function f() {
1479+
return a = 2, 4;
1480+
}
1481+
function g() {
1482+
var t = f();
1483+
return b = a + t;
1484+
}
1485+
var a = 0, b = 1;
1486+
console.log(g());
1487+
}
1488+
expect_stdout: "6"
1489+
}
1490+
1491+
issue_1631_3: {
1492+
options = {
1493+
cascade: true,
1494+
collapse_vars: true,
1495+
hoist_funs: true,
1496+
join_vars: true,
1497+
sequences: true,
1498+
side_effects: true,
1499+
}
1500+
input: {
1501+
function g() {
1502+
var a = 0, b = 1;
1503+
function f() {
1504+
a = 2;
1505+
return 4;
1506+
}
1507+
var t = f();
1508+
b = a + t;
1509+
return b;
1510+
}
1511+
console.log(g());
1512+
}
1513+
expect: {
1514+
function g() {
1515+
function f() {
1516+
return a = 2, 4;
1517+
}
1518+
var a = 0, b = 1, t = f();
1519+
return b = a + t;
1520+
}
1521+
console.log(g());
1522+
}
1523+
expect_stdout: "6"
1524+
}

test/mocha/glob.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var path = require("path");
55
describe("minify() with input file globs", function() {
66
it("minify() with one input file glob string.", function() {
77
var result = Uglify.minify("test/input/issue-1242/foo.*");
8-
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
8+
assert.strictEqual(result.code, 'function foo(o){var n=2*o;print("Foo:",n)}var print=console.log.bind(console);');
99
});
1010
it("minify() with an array of one input file glob.", function() {
1111
var result = Uglify.minify([
@@ -20,7 +20,7 @@ describe("minify() with input file globs", function() {
2020
], {
2121
compress: { toplevel: true }
2222
});
23-
assert.strictEqual(result.code, 'var print=console.log.bind(console);print("qux",function(n){return 3*n}(3),function(n){return n/2}(12)),function(n){print("Foo:",2*n)}(11);');
23+
assert.strictEqual(result.code, 'var print=console.log.bind(console),a=function(n){return 3*n}(3),b=function(n){return n/2}(12);print("qux",a,b),function(n){var o=2*n;print("Foo:",o)}(11);');
2424
});
2525
it("should throw with non-matching glob string", function() {
2626
var glob = "test/input/issue-1242/blah.*";

0 commit comments

Comments
 (0)