index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 _pluginSyntaxPrivatePropertyInObject = require("@babel/plugin-syntax-private-property-in-object");
  8. var _helperCreateClassFeaturesPlugin = require("@babel/helper-create-class-features-plugin");
  9. var _helperAnnotateAsPure = require("@babel/helper-annotate-as-pure");
  10. var _default = (0, _helperPluginUtils.declare)(({
  11. assertVersion,
  12. types: t,
  13. template
  14. }, {
  15. loose
  16. }) => {
  17. assertVersion(7);
  18. const classWeakSets = new WeakMap();
  19. const fieldsWeakSets = new WeakMap();
  20. function unshadow(name, targetScope, scope) {
  21. while (scope !== targetScope) {
  22. if (scope.hasOwnBinding(name)) scope.rename(name);
  23. scope = scope.parent;
  24. }
  25. }
  26. function injectToFieldInit(fieldPath, expr, before = false) {
  27. if (fieldPath.node.value) {
  28. if (before) {
  29. fieldPath.get("value").insertBefore(expr);
  30. } else {
  31. fieldPath.get("value").insertAfter(expr);
  32. }
  33. } else {
  34. fieldPath.set("value", t.unaryExpression("void", expr));
  35. }
  36. }
  37. function injectInitialization(classPath, init) {
  38. let firstFieldPath;
  39. let consturctorPath;
  40. for (const el of classPath.get("body.body")) {
  41. if ((el.isClassProperty() || el.isClassPrivateProperty()) && !el.node.static) {
  42. firstFieldPath = el;
  43. break;
  44. }
  45. if (!consturctorPath && el.isClassMethod({
  46. kind: "constructor"
  47. })) {
  48. consturctorPath = el;
  49. }
  50. }
  51. if (firstFieldPath) {
  52. injectToFieldInit(firstFieldPath, init, true);
  53. } else {
  54. (0, _helperCreateClassFeaturesPlugin.injectInitialization)(classPath, consturctorPath, [t.expressionStatement(init)]);
  55. }
  56. }
  57. function getWeakSetId(weakSets, outerClass, reference, name = "", inject) {
  58. let id = classWeakSets.get(reference.node);
  59. if (!id) {
  60. id = outerClass.scope.generateUidIdentifier(`${name || ""} brandCheck`);
  61. classWeakSets.set(reference.node, id);
  62. inject(reference, template.expression.ast`${t.cloneNode(id)}.add(this)`);
  63. const newExpr = t.newExpression(t.identifier("WeakSet"), []);
  64. (0, _helperAnnotateAsPure.default)(newExpr);
  65. outerClass.insertBefore(template.ast`var ${id} = ${newExpr}`);
  66. }
  67. return t.cloneNode(id);
  68. }
  69. return {
  70. name: "proposal-private-property-in-object",
  71. inherits: _pluginSyntaxPrivatePropertyInObject.default,
  72. pre() {
  73. (0, _helperCreateClassFeaturesPlugin.enableFeature)(this.file, _helperCreateClassFeaturesPlugin.FEATURES.privateIn, loose);
  74. },
  75. visitor: {
  76. BinaryExpression(path) {
  77. const {
  78. node
  79. } = path;
  80. if (node.operator !== "in") return;
  81. if (!t.isPrivateName(node.left)) return;
  82. const {
  83. name
  84. } = node.left.id;
  85. let privateElement;
  86. const outerClass = path.findParent(path => {
  87. if (!path.isClass()) return false;
  88. privateElement = path.get("body.body").find(({
  89. node
  90. }) => t.isPrivate(node) && node.key.id.name === name);
  91. return !!privateElement;
  92. });
  93. if (outerClass.parentPath.scope.path.isPattern()) {
  94. outerClass.replaceWith(template.ast`(() => ${outerClass.node})()`);
  95. return;
  96. }
  97. if (privateElement.isMethod()) {
  98. if (privateElement.node.static) {
  99. if (outerClass.node.id) {
  100. unshadow(outerClass.node.id.name, outerClass.scope, path.scope);
  101. } else {
  102. outerClass.set("id", path.scope.generateUidIdentifier("class"));
  103. }
  104. path.replaceWith(template.expression.ast`
  105. ${t.cloneNode(outerClass.node.id)} === ${path.node.right}
  106. `);
  107. } else {
  108. var _outerClass$node$id;
  109. const id = getWeakSetId(classWeakSets, outerClass, outerClass, (_outerClass$node$id = outerClass.node.id) == null ? void 0 : _outerClass$node$id.name, injectInitialization);
  110. path.replaceWith(template.expression.ast`${id}.has(${path.node.right})`);
  111. }
  112. } else {
  113. const id = getWeakSetId(fieldsWeakSets, outerClass, privateElement, privateElement.node.key.id.name, injectToFieldInit);
  114. path.replaceWith(template.expression.ast`${id}.has(${path.node.right})`);
  115. }
  116. }
  117. }
  118. };
  119. });
  120. exports.default = _default;