3766841573f44928bc3d4130164e8b6f4dc05dd19c8a4f3518b6842558b4dbfca40bc7833cd4a90b9e3488cba8e81e6f50f2a042879ed21e280defa342f362 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _core = require("@babel/core");
  7. const buildClassDecorator = _core.template.statement(`
  8. DECORATOR(CLASS_REF = INNER) || CLASS_REF;
  9. `);
  10. const buildClassPrototype = (0, _core.template)(`
  11. CLASS_REF.prototype;
  12. `);
  13. const buildGetDescriptor = (0, _core.template)(`
  14. Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
  15. `);
  16. const buildGetObjectInitializer = (0, _core.template)(`
  17. (TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
  18. enumerable: true,
  19. configurable: true,
  20. writable: true,
  21. initializer: function(){
  22. return TEMP;
  23. }
  24. })
  25. `);
  26. const WARNING_CALLS = new WeakSet();
  27. function applyEnsureOrdering(path) {
  28. const decorators = (path.isClass() ? [path, ...path.get("body.body")] : path.get("properties")).reduce((acc, prop) => acc.concat(prop.node.decorators || []), []);
  29. const identDecorators = decorators.filter(decorator => !_core.types.isIdentifier(decorator.expression));
  30. if (identDecorators.length === 0) return;
  31. return _core.types.sequenceExpression(identDecorators.map(decorator => {
  32. const expression = decorator.expression;
  33. const id = decorator.expression = path.scope.generateDeclaredUidIdentifier("dec");
  34. return _core.types.assignmentExpression("=", id, expression);
  35. }).concat([path.node]));
  36. }
  37. function applyClassDecorators(classPath) {
  38. if (!hasClassDecorators(classPath.node)) return;
  39. const decorators = classPath.node.decorators || [];
  40. classPath.node.decorators = null;
  41. const name = classPath.scope.generateDeclaredUidIdentifier("class");
  42. return decorators.map(dec => dec.expression).reverse().reduce(function (acc, decorator) {
  43. return buildClassDecorator({
  44. CLASS_REF: _core.types.cloneNode(name),
  45. DECORATOR: _core.types.cloneNode(decorator),
  46. INNER: acc
  47. }).expression;
  48. }, classPath.node);
  49. }
  50. function hasClassDecorators(classNode) {
  51. var _classNode$decorators;
  52. return !!((_classNode$decorators = classNode.decorators) != null && _classNode$decorators.length);
  53. }
  54. function applyMethodDecorators(path, state) {
  55. if (!hasMethodDecorators(path.node.body.body)) return;
  56. return applyTargetDecorators(path, state, path.node.body.body);
  57. }
  58. function hasMethodDecorators(body) {
  59. return body.some(node => {
  60. var _node$decorators;
  61. return ((_node$decorators = node.decorators) == null ? void 0 : _node$decorators.length
  62. );
  63. });
  64. }
  65. function applyObjectDecorators(path, state) {
  66. if (!hasMethodDecorators(path.node.properties)) return;
  67. return applyTargetDecorators(path, state, path.node.properties.filter(prop => prop.type !== "SpreadElement"));
  68. }
  69. function applyTargetDecorators(path, state, decoratedProps) {
  70. const name = path.scope.generateDeclaredUidIdentifier(path.isClass() ? "class" : "obj");
  71. const exprs = decoratedProps.reduce(function (acc, node) {
  72. let decorators = [];
  73. if (node.decorators != null) {
  74. decorators = node.decorators;
  75. node.decorators = null;
  76. }
  77. if (decorators.length === 0) return acc;
  78. if (node.computed) {
  79. throw path.buildCodeFrameError("Computed method/property decorators are not yet supported.");
  80. }
  81. const property = _core.types.isLiteral(node.key) ? node.key : _core.types.stringLiteral(node.key.name);
  82. const target = path.isClass() && !node.static ? buildClassPrototype({
  83. CLASS_REF: name
  84. }).expression : name;
  85. if (_core.types.isClassProperty(node, {
  86. static: false
  87. })) {
  88. const descriptor = path.scope.generateDeclaredUidIdentifier("descriptor");
  89. const initializer = node.value ? _core.types.functionExpression(null, [], _core.types.blockStatement([_core.types.returnStatement(node.value)])) : _core.types.nullLiteral();
  90. node.value = _core.types.callExpression(state.addHelper("initializerWarningHelper"), [descriptor, _core.types.thisExpression()]);
  91. WARNING_CALLS.add(node.value);
  92. acc.push(_core.types.assignmentExpression("=", _core.types.cloneNode(descriptor), _core.types.callExpression(state.addHelper("applyDecoratedDescriptor"), [_core.types.cloneNode(target), _core.types.cloneNode(property), _core.types.arrayExpression(decorators.map(dec => _core.types.cloneNode(dec.expression))), _core.types.objectExpression([_core.types.objectProperty(_core.types.identifier("configurable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("enumerable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("writable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("initializer"), initializer)])])));
  93. } else {
  94. acc.push(_core.types.callExpression(state.addHelper("applyDecoratedDescriptor"), [_core.types.cloneNode(target), _core.types.cloneNode(property), _core.types.arrayExpression(decorators.map(dec => _core.types.cloneNode(dec.expression))), _core.types.isObjectProperty(node) || _core.types.isClassProperty(node, {
  95. static: true
  96. }) ? buildGetObjectInitializer({
  97. TEMP: path.scope.generateDeclaredUidIdentifier("init"),
  98. TARGET: _core.types.cloneNode(target),
  99. PROPERTY: _core.types.cloneNode(property)
  100. }).expression : buildGetDescriptor({
  101. TARGET: _core.types.cloneNode(target),
  102. PROPERTY: _core.types.cloneNode(property)
  103. }).expression, _core.types.cloneNode(target)]));
  104. }
  105. return acc;
  106. }, []);
  107. return _core.types.sequenceExpression([_core.types.assignmentExpression("=", _core.types.cloneNode(name), path.node), _core.types.sequenceExpression(exprs), _core.types.cloneNode(name)]);
  108. }
  109. function decoratedClassToExpression({
  110. node,
  111. scope
  112. }) {
  113. if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) {
  114. return;
  115. }
  116. const ref = node.id ? _core.types.cloneNode(node.id) : scope.generateUidIdentifier("class");
  117. return _core.types.variableDeclaration("let", [_core.types.variableDeclarator(ref, _core.types.toExpression(node))]);
  118. }
  119. const visitor = {
  120. ExportDefaultDeclaration(path) {
  121. const decl = path.get("declaration");
  122. if (!decl.isClassDeclaration()) return;
  123. const replacement = decoratedClassToExpression(decl);
  124. if (replacement) {
  125. const [varDeclPath] = path.replaceWithMultiple([replacement, _core.types.exportNamedDeclaration(null, [_core.types.exportSpecifier(_core.types.cloneNode(replacement.declarations[0].id), _core.types.identifier("default"))])]);
  126. if (!decl.node.id) {
  127. path.scope.registerDeclaration(varDeclPath);
  128. }
  129. }
  130. },
  131. ClassDeclaration(path) {
  132. const replacement = decoratedClassToExpression(path);
  133. if (replacement) {
  134. const [newPath] = path.replaceWith(replacement);
  135. const decl = newPath.get("declarations.0");
  136. const id = decl.node.id;
  137. const binding = path.scope.getOwnBinding(id.name);
  138. binding.identifier = id;
  139. binding.path = decl;
  140. }
  141. },
  142. ClassExpression(path, state) {
  143. const decoratedClass = applyEnsureOrdering(path) || applyClassDecorators(path) || applyMethodDecorators(path, state);
  144. if (decoratedClass) path.replaceWith(decoratedClass);
  145. },
  146. ObjectExpression(path, state) {
  147. const decoratedObject = applyEnsureOrdering(path) || applyObjectDecorators(path, state);
  148. if (decoratedObject) path.replaceWith(decoratedObject);
  149. },
  150. AssignmentExpression(path, state) {
  151. if (!WARNING_CALLS.has(path.node.right)) return;
  152. path.replaceWith(_core.types.callExpression(state.addHelper("initializerDefineProperty"), [_core.types.cloneNode(path.get("left.object").node), _core.types.stringLiteral(path.get("left.property").node.name || path.get("left.property").node.value), _core.types.cloneNode(path.get("right.arguments")[0].node), _core.types.cloneNode(path.get("right.arguments")[1].node)]));
  153. },
  154. CallExpression(path, state) {
  155. if (path.node.arguments.length !== 3) return;
  156. if (!WARNING_CALLS.has(path.node.arguments[2])) return;
  157. if (path.node.callee.name !== state.addHelper("defineProperty").name) {
  158. return;
  159. }
  160. path.replaceWith(_core.types.callExpression(state.addHelper("initializerDefineProperty"), [_core.types.cloneNode(path.get("arguments")[0].node), _core.types.cloneNode(path.get("arguments")[1].node), _core.types.cloneNode(path.get("arguments.2.arguments")[0].node), _core.types.cloneNode(path.get("arguments.2.arguments")[1].node)]));
  161. }
  162. };
  163. var _default = exports.default = visitor;
  164. //# sourceMappingURL=transformer-legacy.js.map