index.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = function (_ref) {
  4. var messages = _ref.messages,
  5. template = _ref.template,
  6. t = _ref.types;
  7. var buildForOfArray = template("\n for (var KEY = 0; KEY < ARR.length; KEY++) BODY;\n ");
  8. var buildForOfLoose = template("\n for (var LOOP_OBJECT = OBJECT,\n IS_ARRAY = Array.isArray(LOOP_OBJECT),\n INDEX = 0,\n LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) {\n var ID;\n if (IS_ARRAY) {\n if (INDEX >= LOOP_OBJECT.length) break;\n ID = LOOP_OBJECT[INDEX++];\n } else {\n INDEX = LOOP_OBJECT.next();\n if (INDEX.done) break;\n ID = INDEX.value;\n }\n }\n ");
  9. var buildForOf = template("\n var ITERATOR_COMPLETION = true;\n var ITERATOR_HAD_ERROR_KEY = false;\n var ITERATOR_ERROR_KEY = undefined;\n try {\n for (var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; !(ITERATOR_COMPLETION = (STEP_KEY = ITERATOR_KEY.next()).done); ITERATOR_COMPLETION = true) {\n }\n } catch (err) {\n ITERATOR_HAD_ERROR_KEY = true;\n ITERATOR_ERROR_KEY = err;\n } finally {\n try {\n if (!ITERATOR_COMPLETION && ITERATOR_KEY.return) {\n ITERATOR_KEY.return();\n }\n } finally {\n if (ITERATOR_HAD_ERROR_KEY) {\n throw ITERATOR_ERROR_KEY;\n }\n }\n }\n ");
  10. function _ForOfStatementArray(path) {
  11. var node = path.node,
  12. scope = path.scope;
  13. var nodes = [];
  14. var right = node.right;
  15. if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) {
  16. var uid = scope.generateUidIdentifier("arr");
  17. nodes.push(t.variableDeclaration("var", [t.variableDeclarator(uid, right)]));
  18. right = uid;
  19. }
  20. var iterationKey = scope.generateUidIdentifier("i");
  21. var loop = buildForOfArray({
  22. BODY: node.body,
  23. KEY: iterationKey,
  24. ARR: right
  25. });
  26. t.inherits(loop, node);
  27. t.ensureBlock(loop);
  28. var iterationValue = t.memberExpression(right, iterationKey, true);
  29. var left = node.left;
  30. if (t.isVariableDeclaration(left)) {
  31. left.declarations[0].init = iterationValue;
  32. loop.body.body.unshift(left);
  33. } else {
  34. loop.body.body.unshift(t.expressionStatement(t.assignmentExpression("=", left, iterationValue)));
  35. }
  36. if (path.parentPath.isLabeledStatement()) {
  37. loop = t.labeledStatement(path.parentPath.node.label, loop);
  38. }
  39. nodes.push(loop);
  40. return nodes;
  41. }
  42. return {
  43. visitor: {
  44. ForOfStatement: function ForOfStatement(path, state) {
  45. if (path.get("right").isArrayExpression()) {
  46. if (path.parentPath.isLabeledStatement()) {
  47. return path.parentPath.replaceWithMultiple(_ForOfStatementArray(path));
  48. } else {
  49. return path.replaceWithMultiple(_ForOfStatementArray(path));
  50. }
  51. }
  52. var callback = spec;
  53. if (state.opts.loose) callback = loose;
  54. var node = path.node;
  55. var build = callback(path, state);
  56. var declar = build.declar;
  57. var loop = build.loop;
  58. var block = loop.body;
  59. path.ensureBlock();
  60. if (declar) {
  61. block.body.push(declar);
  62. }
  63. block.body = block.body.concat(node.body.body);
  64. t.inherits(loop, node);
  65. t.inherits(loop.body, node.body);
  66. if (build.replaceParent) {
  67. path.parentPath.replaceWithMultiple(build.node);
  68. path.remove();
  69. } else {
  70. path.replaceWithMultiple(build.node);
  71. }
  72. }
  73. }
  74. };
  75. function loose(path, file) {
  76. var node = path.node,
  77. scope = path.scope,
  78. parent = path.parent;
  79. var left = node.left;
  80. var declar = void 0,
  81. id = void 0;
  82. if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
  83. id = left;
  84. } else if (t.isVariableDeclaration(left)) {
  85. id = scope.generateUidIdentifier("ref");
  86. declar = t.variableDeclaration(left.kind, [t.variableDeclarator(left.declarations[0].id, id)]);
  87. } else {
  88. throw file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));
  89. }
  90. var iteratorKey = scope.generateUidIdentifier("iterator");
  91. var isArrayKey = scope.generateUidIdentifier("isArray");
  92. var loop = buildForOfLoose({
  93. LOOP_OBJECT: iteratorKey,
  94. IS_ARRAY: isArrayKey,
  95. OBJECT: node.right,
  96. INDEX: scope.generateUidIdentifier("i"),
  97. ID: id
  98. });
  99. if (!declar) {
  100. loop.body.body.shift();
  101. }
  102. var isLabeledParent = t.isLabeledStatement(parent);
  103. var labeled = void 0;
  104. if (isLabeledParent) {
  105. labeled = t.labeledStatement(parent.label, loop);
  106. }
  107. return {
  108. replaceParent: isLabeledParent,
  109. declar: declar,
  110. node: labeled || loop,
  111. loop: loop
  112. };
  113. }
  114. function spec(path, file) {
  115. var node = path.node,
  116. scope = path.scope,
  117. parent = path.parent;
  118. var left = node.left;
  119. var declar = void 0;
  120. var stepKey = scope.generateUidIdentifier("step");
  121. var stepValue = t.memberExpression(stepKey, t.identifier("value"));
  122. if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
  123. declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue));
  124. } else if (t.isVariableDeclaration(left)) {
  125. declar = t.variableDeclaration(left.kind, [t.variableDeclarator(left.declarations[0].id, stepValue)]);
  126. } else {
  127. throw file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));
  128. }
  129. var iteratorKey = scope.generateUidIdentifier("iterator");
  130. var template = buildForOf({
  131. ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
  132. ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
  133. ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
  134. ITERATOR_KEY: iteratorKey,
  135. STEP_KEY: stepKey,
  136. OBJECT: node.right,
  137. BODY: null
  138. });
  139. var isLabeledParent = t.isLabeledStatement(parent);
  140. var tryBody = template[3].block.body;
  141. var loop = tryBody[0];
  142. if (isLabeledParent) {
  143. tryBody[0] = t.labeledStatement(parent.label, loop);
  144. }
  145. return {
  146. replaceParent: isLabeledParent,
  147. declar: declar,
  148. loop: loop,
  149. node: template
  150. };
  151. }
  152. };
  153. module.exports = exports["default"];