avoid transforming of inner labels and propagation of maps in block scoping transformer - #644

This commit is contained in:
Sebastian McKenzie
2015-01-31 21:27:20 +11:00
parent efaee3d5d9
commit c0299320f0
3 changed files with 33 additions and 13 deletions

View File

@@ -311,9 +311,9 @@ var loopVisitor = {
var replace;
if (t.isLoop(node)) {
state = clone(state);
state.ignoreLabeless = true;
traverse(node, loopVisitor, scope, state);
state.ignoreLabeless = false;
}
if (t.isFunction(node) || t.isLoop(node)) {
@@ -324,9 +324,15 @@ var loopVisitor = {
if (loopText) {
if (node.label) {
// we shouldn't be transforming this because it exists somewhere inside
if (state.innerLabels.indexOf(node.label.name) >= 0) {
return;
}
loopText = loopText + "|" + node.label.name;
} else {
// we shouldn't be dealing with this
// we shouldn't be transforming these statements because
// they don't refer to the actual loop we're scopifying
if (state.ignoreLabeless) return;
// break statements mean something different in this context
@@ -352,6 +358,14 @@ var loopVisitor = {
}
};
var loopLabelVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isLabeledStatement(node)) {
state.innerLabels.push(node.label.name);
}
}
};
/**
* If we're inside of a loop then traverse it and check if it has one of
* the following node types `ReturnStatement`, `BreakStatement`,
@@ -365,12 +379,15 @@ LetScoping.prototype.checkLoop = function () {
var state = {
hasBreakContinue: false,
ignoreLabeless: false,
innerLabels: [],
hasReturn: false,
isLoop: !!this.loopParent,
map: {}
};
traverse(this.block, loopLabelVisitor, this.scope, state);
traverse(this.block, loopVisitor, this.scope, state);
return state;
};

View File

@@ -0,0 +1,14 @@
(function () {
var stack = [];
loop1:
for (let j = 0; j < 10; j++) {
for (let i = 0; i < 10; i++) {
stack.push(() => [i, j]);
break loop1;
}
}
assert.deepEqual(stack.length, 1);
assert.deepEqual(stack[0](), [0, 0]);
})();

View File

@@ -1,11 +0,0 @@
if (true) {
const x = 1;
switch (x) {
case 1: {
function y() {
assert(x, 1);
};
break;
}
}
}