index.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _helperPluginUtils() {
  7. const data = require("@babel/helper-plugin-utils");
  8. _helperPluginUtils = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _core() {
  14. const data = require("@babel/core");
  15. _core = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. var _default = (0, _helperPluginUtils().declare)((api, options) => {
  21. api.assertVersion(7);
  22. const {
  23. loose,
  24. assumeArray
  25. } = options;
  26. if (loose === true && assumeArray === true) {
  27. throw new Error(`The loose and assumeArray options cannot be used together in @babel/plugin-transform-for-of`);
  28. }
  29. if (assumeArray) {
  30. return {
  31. name: "transform-for-of",
  32. visitor: {
  33. ForOfStatement(path) {
  34. const {
  35. scope
  36. } = path;
  37. const {
  38. left,
  39. right,
  40. body
  41. } = path.node;
  42. const i = scope.generateUidIdentifier("i");
  43. let array = scope.maybeGenerateMemoised(right, true);
  44. const inits = [_core().types.variableDeclarator(i, _core().types.numericLiteral(0))];
  45. if (array) {
  46. inits.push(_core().types.variableDeclarator(array, right));
  47. } else {
  48. array = right;
  49. }
  50. const item = _core().types.memberExpression(_core().types.cloneNode(array), _core().types.cloneNode(i), true);
  51. let assignment;
  52. if (_core().types.isVariableDeclaration(left)) {
  53. assignment = left;
  54. assignment.declarations[0].init = item;
  55. } else {
  56. assignment = _core().types.expressionStatement(_core().types.assignmentExpression("=", left, item));
  57. }
  58. const block = _core().types.toBlock(body);
  59. block.body.unshift(assignment);
  60. path.replaceWith(_core().types.forStatement(_core().types.variableDeclaration("let", inits), _core().types.binaryExpression("<", _core().types.cloneNode(i), _core().types.memberExpression(_core().types.cloneNode(array), _core().types.identifier("length"))), _core().types.updateExpression("++", _core().types.cloneNode(i)), block));
  61. }
  62. }
  63. };
  64. }
  65. const pushComputedProps = loose ? pushComputedPropsLoose : pushComputedPropsSpec;
  66. const buildForOfArray = (0, _core().template)(`
  67. for (var KEY = 0, NAME = ARR; KEY < NAME.length; KEY++) BODY;
  68. `);
  69. const buildForOfLoose = (0, _core().template)(`
  70. for (var LOOP_OBJECT = OBJECT,
  71. IS_ARRAY = Array.isArray(LOOP_OBJECT),
  72. INDEX = 0,
  73. LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) {
  74. INTERMEDIATE;
  75. if (IS_ARRAY) {
  76. if (INDEX >= LOOP_OBJECT.length) break;
  77. ID = LOOP_OBJECT[INDEX++];
  78. } else {
  79. INDEX = LOOP_OBJECT.next();
  80. if (INDEX.done) break;
  81. ID = INDEX.value;
  82. }
  83. }
  84. `);
  85. const buildForOf = (0, _core().template)(`
  86. var ITERATOR_COMPLETION = true;
  87. var ITERATOR_HAD_ERROR_KEY = false;
  88. var ITERATOR_ERROR_KEY = undefined;
  89. try {
  90. for (
  91. var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY;
  92. !(ITERATOR_COMPLETION = (STEP_KEY = ITERATOR_KEY.next()).done);
  93. ITERATOR_COMPLETION = true
  94. ) {}
  95. } catch (err) {
  96. ITERATOR_HAD_ERROR_KEY = true;
  97. ITERATOR_ERROR_KEY = err;
  98. } finally {
  99. try {
  100. if (!ITERATOR_COMPLETION && ITERATOR_KEY.return != null) {
  101. ITERATOR_KEY.return();
  102. }
  103. } finally {
  104. if (ITERATOR_HAD_ERROR_KEY) {
  105. throw ITERATOR_ERROR_KEY;
  106. }
  107. }
  108. }
  109. `);
  110. function _ForOfStatementArray(path) {
  111. const {
  112. node,
  113. scope
  114. } = path;
  115. const right = scope.generateUidIdentifierBasedOnNode(node.right, "arr");
  116. const iterationKey = scope.generateUidIdentifier("i");
  117. let loop = buildForOfArray({
  118. BODY: node.body,
  119. KEY: iterationKey,
  120. NAME: right,
  121. ARR: node.right
  122. });
  123. _core().types.inherits(loop, node);
  124. _core().types.ensureBlock(loop);
  125. const iterationValue = _core().types.memberExpression(_core().types.cloneNode(right), _core().types.cloneNode(iterationKey), true);
  126. const left = node.left;
  127. if (_core().types.isVariableDeclaration(left)) {
  128. left.declarations[0].init = iterationValue;
  129. loop.body.body.unshift(left);
  130. } else {
  131. loop.body.body.unshift(_core().types.expressionStatement(_core().types.assignmentExpression("=", left, iterationValue)));
  132. }
  133. if (path.parentPath.isLabeledStatement()) {
  134. loop = _core().types.labeledStatement(path.parentPath.node.label, loop);
  135. }
  136. return [loop];
  137. }
  138. function replaceWithArray(path) {
  139. if (path.parentPath.isLabeledStatement()) {
  140. path.parentPath.replaceWithMultiple(_ForOfStatementArray(path));
  141. } else {
  142. path.replaceWithMultiple(_ForOfStatementArray(path));
  143. }
  144. }
  145. return {
  146. name: "transform-for-of",
  147. visitor: {
  148. ForOfStatement(path, state) {
  149. const right = path.get("right");
  150. if (right.isArrayExpression() || right.isGenericType("Array") || _core().types.isArrayTypeAnnotation(right.getTypeAnnotation())) {
  151. replaceWithArray(path);
  152. return;
  153. }
  154. const {
  155. node
  156. } = path;
  157. const build = pushComputedProps(path, state);
  158. const declar = build.declar;
  159. const loop = build.loop;
  160. const block = loop.body;
  161. path.ensureBlock();
  162. if (declar) {
  163. block.body.push(declar);
  164. }
  165. block.body = block.body.concat(node.body.body);
  166. _core().types.inherits(loop, node);
  167. _core().types.inherits(loop.body, node.body);
  168. if (build.replaceParent) {
  169. path.parentPath.replaceWithMultiple(build.node);
  170. path.remove();
  171. } else {
  172. path.replaceWithMultiple(build.node);
  173. }
  174. }
  175. }
  176. };
  177. function pushComputedPropsLoose(path, file) {
  178. const {
  179. node,
  180. scope,
  181. parent
  182. } = path;
  183. const {
  184. left
  185. } = node;
  186. let declar, id, intermediate;
  187. if (_core().types.isIdentifier(left) || _core().types.isPattern(left) || _core().types.isMemberExpression(left)) {
  188. id = left;
  189. intermediate = null;
  190. } else if (_core().types.isVariableDeclaration(left)) {
  191. id = scope.generateUidIdentifier("ref");
  192. declar = _core().types.variableDeclaration(left.kind, [_core().types.variableDeclarator(left.declarations[0].id, _core().types.identifier(id.name))]);
  193. intermediate = _core().types.variableDeclaration("var", [_core().types.variableDeclarator(_core().types.identifier(id.name))]);
  194. } else {
  195. throw file.buildCodeFrameError(left, `Unknown node type ${left.type} in ForStatement`);
  196. }
  197. const iteratorKey = scope.generateUidIdentifier("iterator");
  198. const isArrayKey = scope.generateUidIdentifier("isArray");
  199. const loop = buildForOfLoose({
  200. LOOP_OBJECT: iteratorKey,
  201. IS_ARRAY: isArrayKey,
  202. OBJECT: node.right,
  203. INDEX: scope.generateUidIdentifier("i"),
  204. ID: id,
  205. INTERMEDIATE: intermediate
  206. });
  207. const isLabeledParent = _core().types.isLabeledStatement(parent);
  208. let labeled;
  209. if (isLabeledParent) {
  210. labeled = _core().types.labeledStatement(parent.label, loop);
  211. }
  212. return {
  213. replaceParent: isLabeledParent,
  214. declar: declar,
  215. node: labeled || loop,
  216. loop: loop
  217. };
  218. }
  219. function pushComputedPropsSpec(path, file) {
  220. const {
  221. node,
  222. scope,
  223. parent
  224. } = path;
  225. const left = node.left;
  226. let declar;
  227. const stepKey = scope.generateUid("step");
  228. const stepValue = _core().types.memberExpression(_core().types.identifier(stepKey), _core().types.identifier("value"));
  229. if (_core().types.isIdentifier(left) || _core().types.isPattern(left) || _core().types.isMemberExpression(left)) {
  230. declar = _core().types.expressionStatement(_core().types.assignmentExpression("=", left, stepValue));
  231. } else if (_core().types.isVariableDeclaration(left)) {
  232. declar = _core().types.variableDeclaration(left.kind, [_core().types.variableDeclarator(left.declarations[0].id, stepValue)]);
  233. } else {
  234. throw file.buildCodeFrameError(left, `Unknown node type ${left.type} in ForStatement`);
  235. }
  236. const template = buildForOf({
  237. ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
  238. ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
  239. ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
  240. ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
  241. STEP_KEY: _core().types.identifier(stepKey),
  242. OBJECT: node.right
  243. });
  244. const isLabeledParent = _core().types.isLabeledStatement(parent);
  245. const tryBody = template[3].block.body;
  246. const loop = tryBody[0];
  247. if (isLabeledParent) {
  248. tryBody[0] = _core().types.labeledStatement(parent.label, loop);
  249. }
  250. return {
  251. replaceParent: isLabeledParent,
  252. declar: declar,
  253. loop: loop,
  254. node: template
  255. };
  256. }
  257. });
  258. exports.default = _default;