hoist.js 2.9 KB

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