From: Alex Lam S.L Date: Tue, 7 Mar 2017 10:38:27 +0000 (+0800) Subject: fix deep cloning of labels (#1565) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=8a8a94a596f57981e2cc65ac37921b154a9992b7;p=UglifyJS.git fix deep cloning of labels (#1565) `AST_Label.references` get `.initialize()` to `[]` every time after `.clone()` So walk down the tree to pick up the cloned `AST_LoopControl` pieces and put it back together. --- diff --git a/lib/ast.js b/lib/ast.js index a2125e70..f7ab52e2 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -91,7 +91,7 @@ var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos }, null); var AST_Node = DEFNODE("Node", "start end", { - clone: function(deep) { + _clone: function(deep) { if (deep) { var self = this.clone(); return self.transform(new TreeTransformer(function(node) { @@ -102,6 +102,9 @@ var AST_Node = DEFNODE("Node", "start end", { } return new this.CTOR(this); }, + clone: function(deep) { + return this._clone(deep); + }, $documentation: "Base class of all AST nodes", $propdoc: { start: "[AST_Token] The first token of this node", @@ -207,6 +210,20 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { this.label._walk(visitor); this.body._walk(visitor); }); + }, + clone: function(deep) { + var node = this._clone(deep); + if (deep) { + var refs = node.label.references; + var label = this.label; + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_LoopControl + && node.label && node.label.thedef === label) { + refs.push(node); + } + })); + } + return node; } }, AST_StatementWithBody); diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index a373de29..53e28152 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1093,3 +1093,32 @@ func_modified: { } } } + +defun_label: { + options = { + passes: 2, + reduce_vars: true, + unused: true, + } + input: { + !function() { + function f(a) { + L: { + if (a) break L; + return 1; + } + } + console.log(f(2)); + }(); + } + expect: { + !function() { + console.log(function(a) { + L: { + if (a) break L; + return 1; + } + }(2)); + }(); + } +}