index.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _helperPluginUtils = require("@babel/helper-plugin-utils");
  7. var _pluginSyntaxFunctionBind = require("@babel/plugin-syntax-function-bind");
  8. var _core = require("@babel/core");
  9. var _default = (0, _helperPluginUtils.declare)(api => {
  10. api.assertVersion(7);
  11. function getTempId(scope) {
  12. let id = scope.path.getData("functionBind");
  13. if (id) return _core.types.cloneNode(id);
  14. id = scope.generateDeclaredUidIdentifier("context");
  15. return scope.path.setData("functionBind", id);
  16. }
  17. function getObject(bind) {
  18. if (_core.types.isExpression(bind.object)) {
  19. return bind.object;
  20. }
  21. return bind.callee.object;
  22. }
  23. function getStaticContext(bind, scope) {
  24. const object = getObject(bind);
  25. return scope.isStatic(object) && (_core.types.isSuper(object) ? _core.types.thisExpression() : object);
  26. }
  27. function inferBindContext(bind, scope) {
  28. const staticContext = getStaticContext(bind, scope);
  29. if (staticContext) return _core.types.cloneNode(staticContext);
  30. const tempId = getTempId(scope);
  31. if (bind.object) {
  32. bind.callee = _core.types.sequenceExpression([_core.types.assignmentExpression("=", tempId, bind.object), bind.callee]);
  33. } else if (_core.types.isMemberExpression(bind.callee)) {
  34. bind.callee.object = _core.types.assignmentExpression("=", tempId, bind.callee.object);
  35. }
  36. return _core.types.cloneNode(tempId);
  37. }
  38. return {
  39. name: "proposal-function-bind",
  40. inherits: _pluginSyntaxFunctionBind.default,
  41. visitor: {
  42. CallExpression({
  43. node,
  44. scope
  45. }) {
  46. const bind = node.callee;
  47. if (!_core.types.isBindExpression(bind)) return;
  48. const context = inferBindContext(bind, scope);
  49. node.callee = _core.types.memberExpression(bind.callee, _core.types.identifier("call"));
  50. node.arguments.unshift(context);
  51. },
  52. BindExpression(path) {
  53. const {
  54. node,
  55. scope
  56. } = path;
  57. const context = inferBindContext(node, scope);
  58. path.replaceWith(_core.types.callExpression(_core.types.memberExpression(node.callee, _core.types.identifier("bind")), [context]));
  59. }
  60. }
  61. };
  62. });
  63. exports.default = _default;