hoist.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.hoist = hoist;
  6. var _core = require("@babel/core");
  7. function hoist(funPath) {
  8. _core.types.assertFunction(funPath.node);
  9. const vars = {
  10. __proto__: null
  11. };
  12. function varDeclToExpr({
  13. node: vdec,
  14. scope
  15. }, includeIdentifiers) {
  16. _core.types.assertVariableDeclaration(vdec);
  17. const exprs = [];
  18. vdec.declarations.forEach(function (dec) {
  19. vars[dec.id.name] = _core.types.identifier(dec.id.name);
  20. scope.removeBinding(dec.id.name);
  21. if (dec.init) {
  22. exprs.push(_core.types.assignmentExpression("=", dec.id, dec.init));
  23. } else if (includeIdentifiers) {
  24. exprs.push(dec.id);
  25. }
  26. });
  27. if (exprs.length === 0) return null;
  28. if (exprs.length === 1) return exprs[0];
  29. return _core.types.sequenceExpression(exprs);
  30. }
  31. funPath.get("body").traverse({
  32. VariableDeclaration: {
  33. exit: function (path) {
  34. const expr = varDeclToExpr(path, false);
  35. if (expr === null) {
  36. path.remove();
  37. } else {
  38. path.replaceWith(_core.types.expressionStatement(expr));
  39. }
  40. path.skip();
  41. }
  42. },
  43. ForStatement: function (path) {
  44. const init = path.get("init");
  45. if (init.isVariableDeclaration()) {
  46. const expr = varDeclToExpr(init, false);
  47. if (expr) {
  48. init.replaceWith(expr);
  49. } else {
  50. init.remove();
  51. }
  52. }
  53. },
  54. ForXStatement: function (path) {
  55. const left = path.get("left");
  56. if (left.isVariableDeclaration()) {
  57. left.replaceWith(varDeclToExpr(left, true));
  58. }
  59. },
  60. FunctionDeclaration: function (path) {
  61. const node = path.node;
  62. vars[node.id.name] = node.id;
  63. const assignment = _core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(node.id), _core.types.functionExpression(path.scope.generateUidIdentifierBasedOnNode(node), node.params, node.body, node.generator, node.async)));
  64. if (path.parentPath.isBlockStatement()) {
  65. path.parentPath.unshiftContainer("body", assignment);
  66. path.remove();
  67. } else {
  68. path.replaceWith(assignment);
  69. }
  70. path.scope.removeBinding(node.id.name);
  71. path.skip();
  72. },
  73. FunctionExpression: function (path) {
  74. path.skip();
  75. },
  76. ArrowFunctionExpression: function (path) {
  77. path.skip();
  78. }
  79. });
  80. const paramNames = {
  81. __proto__: null
  82. };
  83. funPath.get("params").forEach(function (paramPath) {
  84. const param = paramPath.node;
  85. if (_core.types.isIdentifier(param)) {
  86. paramNames[param.name] = param;
  87. } else {}
  88. });
  89. const declarations = [];
  90. Object.keys(vars).forEach(function (name) {
  91. if (!hasOwnProperty.call(paramNames, name)) {
  92. declarations.push(_core.types.variableDeclarator(vars[name], null));
  93. }
  94. });
  95. return declarations;
  96. }
  97. //# sourceMappingURL=hoist.js.map