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.
This commit is contained in:
19
lib/ast.js
19
lib/ast.js
@@ -91,7 +91,7 @@ var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos
|
|||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
var AST_Node = DEFNODE("Node", "start end", {
|
var AST_Node = DEFNODE("Node", "start end", {
|
||||||
clone: function(deep) {
|
_clone: function(deep) {
|
||||||
if (deep) {
|
if (deep) {
|
||||||
var self = this.clone();
|
var self = this.clone();
|
||||||
return self.transform(new TreeTransformer(function(node) {
|
return self.transform(new TreeTransformer(function(node) {
|
||||||
@@ -102,6 +102,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
}
|
}
|
||||||
return new this.CTOR(this);
|
return new this.CTOR(this);
|
||||||
},
|
},
|
||||||
|
clone: function(deep) {
|
||||||
|
return this._clone(deep);
|
||||||
|
},
|
||||||
$documentation: "Base class of all AST nodes",
|
$documentation: "Base class of all AST nodes",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
start: "[AST_Token] The first token of this node",
|
start: "[AST_Token] The first token of this node",
|
||||||
@@ -207,6 +210,20 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
this.label._walk(visitor);
|
this.label._walk(visitor);
|
||||||
this.body._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);
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user