diff --git a/lib/compress.js b/lib/compress.js index e4e5e579..dbba272a 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2689,6 +2689,10 @@ merge(Compressor.prototype, { var self = this; if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self; var defs_by_id = Object.create(null); + var var_names = Object.create(null); + self.enclosed.forEach(function(def) { + var_names[def.name] = true; + }); var tt = new TreeTransformer(function(node) { if (node instanceof AST_VarDef) { var sym = node.name, def, value; @@ -2699,31 +2703,13 @@ merge(Compressor.prototype, { && (value = sym.fixed_value()) === node.value && value instanceof AST_Object) { var defs = new Dictionary(); - var assignments = [ - make_node(AST_VarDef, node, { - name: sym, - value: make_node(AST_Object, value, { - properties: [] - }) - }) - ]; + var assignments = []; value.properties.forEach(function(prop) { - var key = make_node(sym.CTOR, sym, { - name: make_node(AST_Sub, sym, { - expression: sym, - property: make_node(AST_String, prop, { - value: prop.key - }) - }).print_to_string(), - scope: self - }); - defs.set(prop.key, self.def_variable(key)); assignments.push(make_node(AST_VarDef, node, { - name: key, + name: make_sym(prop.key), value: prop.value })); }); - if (assignments.length == 1) return assignments[0]; defs_by_id[def.id] = defs; return MAP.splice(assignments); } @@ -2739,10 +2725,25 @@ merge(Compressor.prototype, { scope: node.expression.scope, thedef: def }); - def.references.push(sym); + sym.reference({}); return sym; } } + + function make_sym(key) { + var prefix = sym.name + "_" + key.replace(/[^a-z_$]+/ig, "_"); + var name = prefix; + for (var i = 0; var_names[name]; i++) name = prefix + "$" + i; + var new_var = make_node(sym.CTOR, sym, { + name: name, + scope: self + }); + var def = self.def_variable(new_var); + defs.set(key, def); + self.enclosed.push(def); + var_names[name] = true; + return new_var; + } }); return self.transform(tt); }); diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 774b3473..85a5c573 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -7,9 +7,6 @@ issue_2377_1: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var obj = { foo: 1, @@ -24,10 +21,10 @@ issue_2377_1: { console.log(obj.foo, obj.cube(3)); } expect: { - var n = 1, o = function(n) { - return n * n * n; + var obj_foo = 1, obj_cube = function(x) { + return x * x * x; }; - console.log(n, o(3)); + console.log(obj_foo, obj_cube(3)); } expect_stdout: "1 27" } @@ -42,9 +39,6 @@ issue_2377_2: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var obj = { foo: 1, @@ -59,8 +53,8 @@ issue_2377_2: { console.log(obj.foo, obj.cube(3)); } expect: { - console.log(1, function(n) { - return n * n * n; + console.log(1, function(x) { + return x * x * x; }(3)); } expect_stdout: "1 27" @@ -76,9 +70,6 @@ issue_2377_3: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var obj = { foo: 1, @@ -105,9 +96,6 @@ direct_access_1: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var a = 0; var obj = { @@ -119,12 +107,12 @@ direct_access_1: { } expect: { var a = 0; - var o = { + var obj = { a: 1, b: 2, }; - for (var r in o) a++; - console.log(a, o.a); + for (var k in obj) a++; + console.log(a, obj.a); } expect_stdout: "2 1" } @@ -136,9 +124,6 @@ direct_access_2: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var o = { a: 1 }; var f = function(k) { @@ -147,9 +132,9 @@ direct_access_2: { console.log(f("a")); } expect: { - var n = { a: 1 }; - console.log(function(o) { - if (n[o]) return "PASS"; + var o = { a: 1 }; + console.log(function(k) { + if (o[k]) return "PASS"; }("a")); } expect_stdout: "PASS" @@ -162,18 +147,15 @@ direct_access_3: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var o = { a: 1 }; o.b; console.log(o.a); } expect: { - var a = { a: 1 }; - a.b; - console.log(a.a); + var o = { a: 1 }; + o.b; + console.log(o.a); } expect_stdout: "1" } @@ -185,9 +167,6 @@ single_use: { toplevel: true, unused: true, } - mangle = { - toplevel: true, - } input: { var obj = { bar: function() { @@ -204,3 +183,40 @@ single_use: { }.bar()); } } + +name_collision: { + options = { + reduce_vars: true, + hoist_props: true, + toplevel: true, + } + input: { + var obj_foo = 1; + var obj_bar = 2; + function f() { + var obj = { + foo: 3, + bar: 4, + "b-r": 5, + "b+r": 6, + "b!r": 7, + }; + console.log(obj_foo, obj.foo, obj.bar, obj["b-r"], obj["b+r"], obj["b!r"]); + } + f(); + } + expect: { + var obj_foo = 1; + var obj_bar = 2; + function f() { + var obj_foo$0 = 3, + obj_bar = 4, + obj_b_r = 5, + obj_b_r$0 = 6, + obj_b_r$1 = 7; + console.log(obj_foo, obj_foo$0, obj_bar, obj_b_r, obj_b_r$0, obj_b_r$1); + } + f(); + } + expect_stdout: "1 3 4 5 6 7" +}