From e30dbbab944f5c3b30e7a92c370a368047f29215 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 2 Mar 2015 01:41:13 +1100 Subject: [PATCH] properly replace labels in spec for of transformer - fixes #913, closes #914 --- .../transformation/transformers/es6/for-of.js | 36 +++-- src/babel/types/builder-keys.json | 5 + .../es6-for-of/break/expected.js | 152 +++++++++--------- 3 files changed, 107 insertions(+), 86 deletions(-) diff --git a/src/babel/transformation/transformers/es6/for-of.js b/src/babel/transformation/transformers/es6/for-of.js index 52cfb28f83..5938d07d8e 100644 --- a/src/babel/transformation/transformers/es6/for-of.js +++ b/src/babel/transformation/transformers/es6/for-of.js @@ -32,7 +32,11 @@ export function ForOfStatement(node, parent, scope, file) { // todo: find out why this is necessary? #538 loop._scopeInfo = node._scopeInfo; - return build.node; + if (build.replaceParent) { + this.parentPath.node = build.node; + } else { + return build.node; + } } var breakVisitor = { @@ -97,7 +101,9 @@ var loose = function (node, parent, scope, file) { scope.traverse(node, breakVisitor, { iteratorKey: iteratorKey, - wrapReturn: function (node) { + label: t.isLabeledStatement(parent) && parent.label.name, + + wrapReturn: function (node) { return t.ifStatement( t.logicalExpression( "&&", @@ -105,8 +111,7 @@ var loose = function (node, parent, scope, file) { t.memberExpression(iteratorKey, t.identifier("return") ) ), node); - }, - label: t.isLabeledStatement(parent) && parent.label.name + } }); // @@ -119,6 +124,8 @@ var loose = function (node, parent, scope, file) { }; var spec = function (node, parent, scope, file) { + + var left = node.left; var declar; @@ -151,14 +158,22 @@ var spec = function (node, parent, scope, file) { BODY: null }); - var loop = template[3].block.body[0]; + var isLabeledParent = t.isLabeledStatement(parent); + + var tryBody = template[3].block.body; + var loop = tryBody[0]; + + if (isLabeledParent) { + tryBody[0] = t.labeledStatement(parent.label, loop); + } // scope.traverse(node, breakVisitor, { iteratorKey: iteratorKey, - label: t.isLabeledStatement(parent) && parent.label.name, - wrapReturn: function (node) { + label: isLabeledParent && parent.label.name, + + wrapReturn: function (node) { return t.ifStatement(t.memberExpression(iteratorKey, t.identifier("return")), node); } }); @@ -166,8 +181,9 @@ var spec = function (node, parent, scope, file) { // return { - declar: declar, - loop: loop, - node: template + replaceParent: isLabeledParent, + declar: declar, + loop: loop, + node: template }; }; diff --git a/src/babel/types/builder-keys.json b/src/babel/types/builder-keys.json index 129d3582d5..a9bf34c0a9 100644 --- a/src/babel/types/builder-keys.json +++ b/src/babel/types/builder-keys.json @@ -84,6 +84,11 @@ "name": null }, + "LabeledStatement": { + "label": null, + "body": null + }, + "Literal": { "value": null }, diff --git a/test/fixtures/transformation/es6-for-of/break/expected.js b/test/fixtures/transformation/es6-for-of/break/expected.js index 92c8f3eaa6..a88946704a 100644 --- a/test/fixtures/transformation/es6-for-of/break/expected.js +++ b/test/fixtures/transformation/es6-for-of/break/expected.js @@ -2,89 +2,89 @@ // labels -foo: { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; +var _iteratorNormalCompletion = true; +var _didIteratorError = false; +var _iteratorError = undefined; - try { - for (var _iterator = foo()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var x = _step.value; +try { + foo: for (var _iterator = foo()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var x = _step.value; - while (true) { - if (_iterator["return"]) _iterator["return"](); - - break foo; - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } -}foo: { - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = foo()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var x = _step2.value; - - while (true) { - break; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } -}foo: { - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = foo()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var x = _step3.value; - if (_iterator3["return"]) _iterator3["return"](); + while (true) { + if (_iterator["return"]) _iterator["return"](); break foo; } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; + } +} catch (err) { + _didIteratorError = true; + _iteratorError = err; +} finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } + if (_didIteratorError) { + throw _iteratorError; } } -} // basic +} + +var _iteratorNormalCompletion2 = true; +var _didIteratorError2 = false; +var _iteratorError2 = undefined; + +try { + foo: for (var _iterator2 = foo()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var x = _step2.value; + + while (true) { + break; + } + } +} catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; +} finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } +} + +var _iteratorNormalCompletion3 = true; +var _didIteratorError3 = false; +var _iteratorError3 = undefined; + +try { + foo: for (var _iterator3 = foo()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var x = _step3.value; + if (_iterator3["return"]) _iterator3["return"](); + + break foo; + } +} catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; +} finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } +} + +// basic var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; @@ -137,4 +137,4 @@ try { throw _iteratorError5; } } -} \ No newline at end of file +}