From 23b5eeb72f2abb4eca54a5753468344eb2373d44 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 13 Feb 2015 21:05:21 +1100 Subject: [PATCH] use Symbol.iterator in for symbol detection and add the conversion of it to the selfContained transformer - @zloirock --- .../templates/corejs-is-iterator.js | 1 + .../templates/sliced-to-array.js | 8 +++--- .../transformers/other/self-contained.js | 28 ++++++++++++++----- .../es6-destructuring/array/expected.js | 2 +- .../assignment-expression/expected.js | 2 +- .../assignment-statement/expected.js | 2 +- .../es6-destructuring/empty/expected.js | 2 +- .../es6-destructuring/for-in/expected.js | 2 +- .../es6-destructuring/for-of/expected.js | 2 +- .../member-expression/expected.js | 2 +- .../es6-destructuring/mixed/expected.js | 2 +- .../es6-destructuring/parameters/expected.js | 2 +- .../symbol-iterator-in/actual.js | 1 + .../symbol-iterator-in/expected.js | 5 ++++ 14 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 lib/6to5/transformation/templates/corejs-is-iterator.js create mode 100644 test/fixtures/transformation/self-contained/symbol-iterator-in/actual.js create mode 100644 test/fixtures/transformation/self-contained/symbol-iterator-in/expected.js diff --git a/lib/6to5/transformation/templates/corejs-is-iterator.js b/lib/6to5/transformation/templates/corejs-is-iterator.js new file mode 100644 index 0000000000..6a18378f0f --- /dev/null +++ b/lib/6to5/transformation/templates/corejs-is-iterator.js @@ -0,0 +1 @@ +CORE_ID.$for.isIterable(VALUE); diff --git a/lib/6to5/transformation/templates/sliced-to-array.js b/lib/6to5/transformation/templates/sliced-to-array.js index af2f04e8e7..274222b0c6 100644 --- a/lib/6to5/transformation/templates/sliced-to-array.js +++ b/lib/6to5/transformation/templates/sliced-to-array.js @@ -1,14 +1,14 @@ (function (arr, i) { - if (!arr || !arr[Symbol.iterator]) { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } else if (Array.isArray(arr)) { + if (Array.isArray(arr)) { return arr; - } else { + } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }); diff --git a/lib/6to5/transformation/transformers/other/self-contained.js b/lib/6to5/transformation/transformers/other/self-contained.js index 7be61ec9e9..0267ef16f9 100644 --- a/lib/6to5/transformation/transformers/other/self-contained.js +++ b/lib/6to5/transformation/transformers/other/self-contained.js @@ -40,20 +40,34 @@ var astVisitor = { } else if (t.isCallExpression(node)) { // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) - if (node.arguments.length) return; - var callee = node.callee; - if (!t.isMemberExpression(callee)) return; - if (!callee.computed) return; + if (node.arguments.length) return false; + + if (!t.isMemberExpression(callee)) return false; + if (!callee.computed) return false; prop = callee.property; - if (!t.isIdentifier(prop.object, { name: "Symbol" })) return; - if (!t.isIdentifier(prop.property, { name: "iterator" })) return; + if (!t.isIdentifier(prop.object, { name: "Symbol" })) return false; + if (!t.isIdentifier(prop.property, { name: "iterator" })) return false; return util.template("corejs-iterator", { CORE_ID: file.get("coreIdentifier"), VALUE: callee.object }); + } else if (t.isBinaryExpression(node)) { + // Symbol.iterator in arr -> core.$for.isIterable(arr) + + if (node.operator !== "in") return; + + var left = node.left; + if (!t.isMemberExpression(left)) return; + if (!t.isIdentifier(left.object, { name: "Symbol" })) return; + if (!t.isIdentifier(left.property, { name: "iterator" })) return; + + return util.template("corejs-is-iterator", { + CORE_ID: file.get("coreIdentifier"), + VALUE: node.right + }); } } }; @@ -83,7 +97,7 @@ exports.pre = function (file) { }; exports.Identifier = function (node, parent, scope, file) { - if (node.name === "regeneratorRuntime" && t.isReferenced(node, parent)) { + if (t.isReferencedIdentifier(node, parent, { name: "regeneratorRuntime" })) { return file.get("regeneratorIdentifier"); } }; diff --git a/test/fixtures/transformation/es6-destructuring/array/expected.js b/test/fixtures/transformation/es6-destructuring/array/expected.js index 80f0f225e7..1c128a89f2 100644 --- a/test/fixtures/transformation/es6-destructuring/array/expected.js +++ b/test/fixtures/transformation/es6-destructuring/array/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var _ref = ["hello", [", ", "junk"], ["world"]]; diff --git a/test/fixtures/transformation/es6-destructuring/assignment-expression/expected.js b/test/fixtures/transformation/es6-destructuring/assignment-expression/expected.js index dc77a31667..07ada2afa8 100644 --- a/test/fixtures/transformation/es6-destructuring/assignment-expression/expected.js +++ b/test/fixtures/transformation/es6-destructuring/assignment-expression/expected.js @@ -1,6 +1,6 @@ "use strict"; var _temp, _temp2; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; console.log((_temp = [123], _temp2 = _slicedToArray(_temp, 1), x = _temp2[0], _temp)); diff --git a/test/fixtures/transformation/es6-destructuring/assignment-statement/expected.js b/test/fixtures/transformation/es6-destructuring/assignment-statement/expected.js index 858f09bbdc..71ca802c0b 100644 --- a/test/fixtures/transformation/es6-destructuring/assignment-statement/expected.js +++ b/test/fixtures/transformation/es6-destructuring/assignment-statement/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var _ref = f(); diff --git a/test/fixtures/transformation/es6-destructuring/empty/expected.js b/test/fixtures/transformation/es6-destructuring/empty/expected.js index 1d65a1a529..2dfc21dee2 100644 --- a/test/fixtures/transformation/es6-destructuring/empty/expected.js +++ b/test/fixtures/transformation/es6-destructuring/empty/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var _ref = ["foo", "hello", [", ", "junk"], ["world"]]; diff --git a/test/fixtures/transformation/es6-destructuring/for-in/expected.js b/test/fixtures/transformation/es6-destructuring/for-in/expected.js index f745b66aaf..c320f40d12 100644 --- a/test/fixtures/transformation/es6-destructuring/for-in/expected.js +++ b/test/fixtures/transformation/es6-destructuring/for-in/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; for (var _ref in obj) { var _ref2 = _slicedToArray(_ref, 2); diff --git a/test/fixtures/transformation/es6-destructuring/for-of/expected.js b/test/fixtures/transformation/es6-destructuring/for-of/expected.js index 0153f013e7..fd33a1590e 100644 --- a/test/fixtures/transformation/es6-destructuring/for-of/expected.js +++ b/test/fixtures/transformation/es6-destructuring/for-of/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; for (var _iterator = test.expectation.registers[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { var _step$value = _slicedToArray(_step.value, 3); diff --git a/test/fixtures/transformation/es6-destructuring/member-expression/expected.js b/test/fixtures/transformation/es6-destructuring/member-expression/expected.js index bde82a9e06..2deb4b752d 100644 --- a/test/fixtures/transformation/es6-destructuring/member-expression/expected.js +++ b/test/fixtures/transformation/es6-destructuring/member-expression/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var _ref = [1, 2]; diff --git a/test/fixtures/transformation/es6-destructuring/mixed/expected.js b/test/fixtures/transformation/es6-destructuring/mixed/expected.js index b350be4d80..6e97718460 100644 --- a/test/fixtures/transformation/es6-destructuring/mixed/expected.js +++ b/test/fixtures/transformation/es6-destructuring/mixed/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var _rect$topLeft = _slicedToArray(rect.topLeft, 2); diff --git a/test/fixtures/transformation/es6-destructuring/parameters/expected.js b/test/fixtures/transformation/es6-destructuring/parameters/expected.js index e1332ba704..9608e1e16e 100644 --- a/test/fixtures/transformation/es6-destructuring/parameters/expected.js +++ b/test/fixtures/transformation/es6-destructuring/parameters/expected.js @@ -1,6 +1,6 @@ "use strict"; -var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } }; +var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; function somethingAdvanced(_ref) { var _ref$topLeft = _ref.topLeft; diff --git a/test/fixtures/transformation/self-contained/symbol-iterator-in/actual.js b/test/fixtures/transformation/self-contained/symbol-iterator-in/actual.js new file mode 100644 index 0000000000..49e71aa52d --- /dev/null +++ b/test/fixtures/transformation/self-contained/symbol-iterator-in/actual.js @@ -0,0 +1 @@ +Symbol.iterator in Object(arr); diff --git a/test/fixtures/transformation/self-contained/symbol-iterator-in/expected.js b/test/fixtures/transformation/self-contained/symbol-iterator-in/expected.js new file mode 100644 index 0000000000..5c74f87cbf --- /dev/null +++ b/test/fixtures/transformation/self-contained/symbol-iterator-in/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +var _core = require("6to5-runtime/core-js"); + +_core.$for.isIterable(Object(arr));