renamer.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _binding = require("../binding");
  7. var _helperSplitExportDeclaration = require("@babel/helper-split-export-declaration");
  8. var _t = require("@babel/types");
  9. const {
  10. VISITOR_KEYS,
  11. assignmentExpression,
  12. identifier,
  13. toExpression,
  14. variableDeclaration,
  15. variableDeclarator
  16. } = _t;
  17. const renameVisitor = {
  18. ReferencedIdentifier({
  19. node
  20. }, state) {
  21. if (node.name === state.oldName) {
  22. node.name = state.newName;
  23. }
  24. },
  25. Scope(path, state) {
  26. if (!path.scope.bindingIdentifierEquals(state.oldName, state.binding.identifier)) {
  27. skipAllButComputedMethodKey(path);
  28. }
  29. },
  30. "AssignmentExpression|Declaration|VariableDeclarator"(path, state) {
  31. if (path.isVariableDeclaration()) return;
  32. const ids = path.getOuterBindingIdentifiers();
  33. for (const name in ids) {
  34. if (name === state.oldName) ids[name].name = state.newName;
  35. }
  36. }
  37. };
  38. class Renamer {
  39. constructor(binding, oldName, newName) {
  40. this.newName = newName;
  41. this.oldName = oldName;
  42. this.binding = binding;
  43. }
  44. maybeConvertFromExportDeclaration(parentDeclar) {
  45. const maybeExportDeclar = parentDeclar.parentPath;
  46. if (!maybeExportDeclar.isExportDeclaration()) {
  47. return;
  48. }
  49. if (maybeExportDeclar.isExportDefaultDeclaration() && !maybeExportDeclar.get("declaration").node.id) {
  50. return;
  51. }
  52. (0, _helperSplitExportDeclaration.default)(maybeExportDeclar);
  53. }
  54. maybeConvertFromClassFunctionDeclaration(path) {
  55. return;
  56. if (!path.isFunctionDeclaration() && !path.isClassDeclaration()) return;
  57. if (this.binding.kind !== "hoisted") return;
  58. path.node.id = identifier(this.oldName);
  59. path.node._blockHoist = 3;
  60. path.replaceWith(variableDeclaration("let", [variableDeclarator(identifier(this.newName), toExpression(path.node))]));
  61. }
  62. maybeConvertFromClassFunctionExpression(path) {
  63. return;
  64. if (!path.isFunctionExpression() && !path.isClassExpression()) return;
  65. if (this.binding.kind !== "local") return;
  66. path.node.id = identifier(this.oldName);
  67. this.binding.scope.parent.push({
  68. id: identifier(this.newName)
  69. });
  70. path.replaceWith(assignmentExpression("=", identifier(this.newName), path.node));
  71. }
  72. rename(block) {
  73. const {
  74. binding,
  75. oldName,
  76. newName
  77. } = this;
  78. const {
  79. scope,
  80. path
  81. } = binding;
  82. const parentDeclar = path.find(path => path.isDeclaration() || path.isFunctionExpression() || path.isClassExpression());
  83. if (parentDeclar) {
  84. const bindingIds = parentDeclar.getOuterBindingIdentifiers();
  85. if (bindingIds[oldName] === binding.identifier) {
  86. this.maybeConvertFromExportDeclaration(parentDeclar);
  87. }
  88. }
  89. const blockToTraverse = block || scope.block;
  90. if ((blockToTraverse == null ? void 0 : blockToTraverse.type) === "SwitchStatement") {
  91. blockToTraverse.cases.forEach(c => {
  92. scope.traverse(c, renameVisitor, this);
  93. });
  94. } else {
  95. scope.traverse(blockToTraverse, renameVisitor, this);
  96. }
  97. if (!block) {
  98. scope.removeOwnBinding(oldName);
  99. scope.bindings[newName] = binding;
  100. this.binding.identifier.name = newName;
  101. }
  102. if (parentDeclar) {
  103. this.maybeConvertFromClassFunctionDeclaration(parentDeclar);
  104. this.maybeConvertFromClassFunctionExpression(parentDeclar);
  105. }
  106. }
  107. }
  108. exports.default = Renamer;
  109. function skipAllButComputedMethodKey(path) {
  110. if (!path.isMethod() || !path.node.computed) {
  111. path.skip();
  112. return;
  113. }
  114. const keys = VISITOR_KEYS[path.type];
  115. for (const key of keys) {
  116. if (key !== "key") path.skipKey(key);
  117. }
  118. }