diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-11-19 16:02:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-20 00:02:25 +0800 |
commit | b18b70f63bce53f1e19ad53c35cef6860b736ea6 (patch) | |
tree | f82121756a2ffc89e669d2a4176810f9e54b1ec9 | |
parent | 641406d4910a8991cbd41b0814fedd5f38958850 (diff) | |
download | tracifyjs-b18b70f63bce53f1e19ad53c35cef6860b736ea6.tar.gz tracifyjs-b18b70f63bce53f1e19ad53c35cef6860b736ea6.zip |
fix corner case in `hoist_props` (#4307)
-rw-r--r-- | lib/compress.js | 50 | ||||
-rw-r--r-- | test/compress/hoist_props.js | 27 |
2 files changed, 54 insertions, 23 deletions
diff --git a/lib/compress.js b/lib/compress.js index 23eb5e44..90488807 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4611,12 +4611,7 @@ merge(Compressor.prototype, { if (len < self.argnames.length && !compressor.drop_fargs(self, compressor.parent())) { if (!compressor.drop_fargs(fn, call)) break; do { - var argname = make_node(AST_SymbolFunarg, fn, { - name: fn.make_var_name("argument_" + len), - scope: fn - }); - fn.argnames.push(argname); - fn.enclosed.push(fn.def_variable(argname)); + fn.argnames.push(fn.make_var(AST_SymbolFunarg, fn, "argument_" + len)); } while (++len < self.argnames.length); } return call.expression; @@ -5984,13 +5979,31 @@ merge(Compressor.prototype, { return var_names; }); - AST_Scope.DEFMETHOD("make_var_name", function(prefix) { - var var_names = this.var_names(); + AST_Scope.DEFMETHOD("make_var", function(type, orig, prefix) { + var scopes = [ this ]; + if (orig instanceof AST_SymbolDeclaration) orig.definition().references.forEach(function(ref) { + var s = ref.scope; + if (member(s, scopes)) return; + do { + push_uniq(scopes, s); + s = s.parent_scope; + } while (s && s !== this); + }); prefix = prefix.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_"); var name = prefix; - for (var i = 0; var_names[name]; i++) name = prefix + "$" + i; - var_names[name] = true; - return name; + for (var i = 0; !all(scopes, function(scope) { + return !scope.var_names()[name]; + }); i++) name = prefix + "$" + i; + var sym = make_node(type, orig, { + name: name, + scope: this, + }); + var def = this.def_variable(sym); + scopes.forEach(function(scope) { + scope.enclosed.push(def); + scope.var_names()[name] = true; + }); + return sym; }); AST_Scope.DEFMETHOD("hoist_properties", function(compressor) { @@ -6049,13 +6062,8 @@ merge(Compressor.prototype, { } function make_sym(sym, key) { - var new_var = make_node(AST_SymbolVar, sym, { - name: self.make_var_name(sym.name + "_" + key), - scope: self - }); - var def = self.def_variable(new_var); - defs.set(key, def); - self.enclosed.push(def); + var new_var = self.make_var(AST_SymbolVar, sym, sym.name + "_" + key); + defs.set(key, new_var.definition()); return new_var; } })); @@ -9623,12 +9631,8 @@ merge(Compressor.prototype, { } } else if (!argname && index < fn.argnames.length + 5 && compressor.drop_fargs(fn, fn_parent)) { while (index >= fn.argnames.length) { - argname = make_node(AST_SymbolFunarg, fn, { - name: fn.make_var_name("argument_" + fn.argnames.length), - scope: fn - }); + argname = fn.make_var(AST_SymbolFunarg, fn, "argument_" + fn.argnames.length); fn.argnames.push(argname); - fn.enclosed.push(fn.def_variable(argname)); } } if (argname && find_if(function(node) { diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 09137cc9..dbee9b42 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -297,6 +297,33 @@ name_collision_3: { expect_stdout: "true 4 6" } +name_collision_4: { + options = { + hoist_props: true, + reduce_vars: true, + } + input: { + console.log(function() { + var o = { + p: 0, + q: "PASS", + }; + return function(o_p) { + if (!o.p) return o_p; + }(o.q); + }()); + } + expect: { + console.log(function() { + var o_p$0 = 0, o_q = "PASS"; + return function(o_p) { + if (!o_p$0) return o_p; + }(o_q); + }()); + } + expect_stdout: "PASS" +} + contains_this_1: { options = { evaluate: true, |