decorators.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.hasOwnDecorators = hasOwnDecorators;
  6. exports.hasDecorators = hasDecorators;
  7. exports.buildDecoratedClass = buildDecoratedClass;
  8. function _core() {
  9. const data = require("@babel/core");
  10. _core = function () {
  11. return data;
  12. };
  13. return data;
  14. }
  15. function _helperReplaceSupers() {
  16. const data = _interopRequireDefault(require("@babel/helper-replace-supers"));
  17. _helperReplaceSupers = function () {
  18. return data;
  19. };
  20. return data;
  21. }
  22. function _helperFunctionName() {
  23. const data = _interopRequireDefault(require("@babel/helper-function-name"));
  24. _helperFunctionName = function () {
  25. return data;
  26. };
  27. return data;
  28. }
  29. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  30. function hasOwnDecorators(node) {
  31. return !!(node.decorators && node.decorators.length);
  32. }
  33. function hasDecorators(node) {
  34. return hasOwnDecorators(node) || node.body.body.some(hasOwnDecorators);
  35. }
  36. function prop(key, value) {
  37. if (!value) return null;
  38. return _core().types.objectProperty(_core().types.identifier(key), value);
  39. }
  40. function method(key, body) {
  41. return _core().types.objectMethod("method", _core().types.identifier(key), [], _core().types.blockStatement(body));
  42. }
  43. function takeDecorators(node) {
  44. let result;
  45. if (node.decorators && node.decorators.length > 0) {
  46. result = _core().types.arrayExpression(node.decorators.map(decorator => decorator.expression));
  47. }
  48. node.decorators = undefined;
  49. return result;
  50. }
  51. function getKey(node) {
  52. if (node.computed) {
  53. return node.key;
  54. } else if (_core().types.isIdentifier(node.key)) {
  55. return _core().types.stringLiteral(node.key.name);
  56. } else {
  57. return _core().types.stringLiteral(String(node.key.value));
  58. }
  59. }
  60. function extractElementDescriptor(classRef, superRef, path) {
  61. const {
  62. node,
  63. scope
  64. } = path;
  65. const isMethod = path.isClassMethod();
  66. if (path.isPrivate()) {
  67. throw path.buildCodeFrameError(`Private ${isMethod ? "methods" : "fields"} in decorated classes are not supported yet.`);
  68. }
  69. new (_helperReplaceSupers().default)({
  70. methodPath: path,
  71. methodNode: node,
  72. objectRef: classRef,
  73. isStatic: node.static,
  74. superRef,
  75. scope,
  76. file: this
  77. }, true).replace();
  78. const properties = [prop("kind", _core().types.stringLiteral(isMethod ? node.kind : "field")), prop("decorators", takeDecorators(node)), prop("static", node.static && _core().types.booleanLiteral(true)), prop("key", getKey(node))].filter(Boolean);
  79. if (isMethod) {
  80. const id = node.computed ? null : node.key;
  81. _core().types.toExpression(node);
  82. properties.push(prop("value", (0, _helperFunctionName().default)({
  83. node,
  84. id,
  85. scope
  86. }) || node));
  87. } else if (node.value) {
  88. properties.push(method("value", _core().template.statements.ast`return ${node.value}`));
  89. } else {
  90. properties.push(prop("value", scope.buildUndefinedNode()));
  91. }
  92. path.remove();
  93. return _core().types.objectExpression(properties);
  94. }
  95. function addDecorateHelper(file) {
  96. try {
  97. return file.addHelper("decorate");
  98. } catch (err) {
  99. if (err.code === "BABEL_HELPER_UNKNOWN") {
  100. err.message += "\n '@babel/plugin-transform-decorators' in non-legacy mode" + " requires '@babel/core' version ^7.0.2 and you appear to be using" + " an older version.";
  101. }
  102. throw err;
  103. }
  104. }
  105. function buildDecoratedClass(ref, path, elements, file) {
  106. const {
  107. node,
  108. scope
  109. } = path;
  110. const initializeId = scope.generateUidIdentifier("initialize");
  111. const isDeclaration = node.id && path.isDeclaration();
  112. const isStrict = path.isInStrictMode();
  113. const {
  114. superClass
  115. } = node;
  116. node.type = "ClassDeclaration";
  117. if (!node.id) node.id = _core().types.cloneNode(ref);
  118. let superId;
  119. if (superClass) {
  120. superId = scope.generateUidIdentifierBasedOnNode(node.superClass, "super");
  121. node.superClass = superId;
  122. }
  123. const classDecorators = takeDecorators(node);
  124. const definitions = _core().types.arrayExpression(elements.map(extractElementDescriptor.bind(file, node.id, superId)));
  125. let replacement = _core().template.expression.ast`
  126. ${addDecorateHelper(file)}(
  127. ${classDecorators || _core().types.nullLiteral()},
  128. function (${initializeId}, ${superClass ? superId : null}) {
  129. ${node}
  130. return { F: ${_core().types.cloneNode(node.id)}, d: ${definitions} };
  131. },
  132. ${superClass}
  133. )
  134. `;
  135. let classPathDesc = "arguments.1.body.body.0";
  136. if (!isStrict) {
  137. replacement.arguments[1].body.directives.push(_core().types.directive(_core().types.directiveLiteral("use strict")));
  138. }
  139. if (isDeclaration) {
  140. replacement = _core().template.ast`let ${ref} = ${replacement}`;
  141. classPathDesc = "declarations.0.init." + classPathDesc;
  142. }
  143. return {
  144. instanceNodes: [_core().template.statement.ast`${initializeId}(this)`],
  145. wrapClass(path) {
  146. path.replaceWith(replacement);
  147. return path.get(classPathDesc);
  148. }
  149. };
  150. }