index.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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 _pluginTransformDestructuring = require("@babel/plugin-transform-destructuring");
  8. var _core = require("@babel/core");
  9. function isAnonymousFunctionDefinition(node) {
  10. return _core.types.isArrowFunctionExpression(node) || (_core.types.isFunctionExpression(node) || _core.types.isClassExpression(node)) && !node.id;
  11. }
  12. function emitSetFunctionNameCall(state, expression, name) {
  13. return _core.types.callExpression(state.addHelper("setFunctionName"), [expression, _core.types.stringLiteral(name)]);
  14. }
  15. var _default = exports.default = (0, _helperPluginUtils.declare)(api => {
  16. api.assertVersion("^7.23.9 || >8.0.0-alpha <8.0.0-beta");
  17. const TOP_LEVEL_USING = new Map();
  18. function isUsingDeclaration(node) {
  19. if (!_core.types.isVariableDeclaration(node)) return false;
  20. return node.kind === "using" || node.kind === "await using" || TOP_LEVEL_USING.has(node);
  21. }
  22. const transformUsingDeclarationsVisitor = {
  23. ForOfStatement(path) {
  24. const {
  25. left
  26. } = path.node;
  27. if (!isUsingDeclaration(left)) return;
  28. const {
  29. id
  30. } = left.declarations[0];
  31. const tmpId = path.scope.generateUidIdentifierBasedOnNode(id);
  32. left.declarations[0].id = tmpId;
  33. left.kind = "const";
  34. path.ensureBlock();
  35. (0, _pluginTransformDestructuring.unshiftForXStatementBody)(path, [_core.types.variableDeclaration("using", [_core.types.variableDeclarator(id, _core.types.cloneNode(tmpId))])]);
  36. },
  37. "BlockStatement|StaticBlock"(path, state) {
  38. let ctx = null;
  39. let needsAwait = false;
  40. const scope = path.scope;
  41. for (const node of path.node.body) {
  42. if (!isUsingDeclaration(node)) continue;
  43. ctx != null ? ctx : ctx = scope.generateUidIdentifier("usingCtx");
  44. const isAwaitUsing = node.kind === "await using" || TOP_LEVEL_USING.get(node) === 1;
  45. needsAwait || (needsAwait = isAwaitUsing);
  46. if (!TOP_LEVEL_USING.delete(node)) {
  47. node.kind = "const";
  48. }
  49. for (const decl of node.declarations) {
  50. const currentInit = decl.init;
  51. decl.init = _core.types.callExpression(_core.types.memberExpression(_core.types.cloneNode(ctx), isAwaitUsing ? _core.types.identifier("a") : _core.types.identifier("u")), [isAnonymousFunctionDefinition(currentInit) && _core.types.isIdentifier(decl.id) ? emitSetFunctionNameCall(state, currentInit, decl.id.name) : currentInit]);
  52. }
  53. }
  54. if (!ctx) return;
  55. const disposeCall = _core.types.callExpression(_core.types.memberExpression(_core.types.cloneNode(ctx), _core.types.identifier("d")), []);
  56. const replacement = _core.template.statement.ast`
  57. try {
  58. var ${_core.types.cloneNode(ctx)} = ${state.addHelper("usingCtx")}();
  59. ${path.node.body}
  60. } catch (_) {
  61. ${_core.types.cloneNode(ctx)}.e = _;
  62. } finally {
  63. ${needsAwait ? _core.types.awaitExpression(disposeCall) : disposeCall}
  64. }
  65. `;
  66. _core.types.inherits(replacement, path.node);
  67. const {
  68. parentPath
  69. } = path;
  70. if (parentPath.isFunction() || parentPath.isTryStatement() || parentPath.isCatchClause()) {
  71. path.replaceWith(_core.types.blockStatement([replacement]));
  72. } else if (path.isStaticBlock()) {
  73. path.node.body = [replacement];
  74. } else {
  75. path.replaceWith(replacement);
  76. }
  77. }
  78. };
  79. const transformUsingDeclarationsVisitorSkipFn = _core.traverse.visitors.merge([transformUsingDeclarationsVisitor, {
  80. Function(path) {
  81. path.skip();
  82. }
  83. }]);
  84. return {
  85. name: "transform-explicit-resource-management",
  86. manipulateOptions: (_, p) => p.plugins.push("explicitResourceManagement"),
  87. visitor: _core.traverse.visitors.merge([transformUsingDeclarationsVisitor, {
  88. Program(path) {
  89. TOP_LEVEL_USING.clear();
  90. if (path.node.sourceType !== "module") return;
  91. if (!path.node.body.some(isUsingDeclaration)) return;
  92. const innerBlockBody = [];
  93. for (const stmt of path.get("body")) {
  94. if (stmt.isFunctionDeclaration() || stmt.isImportDeclaration()) {
  95. continue;
  96. }
  97. let node = stmt.node;
  98. let shouldRemove = true;
  99. if (stmt.isExportDefaultDeclaration()) {
  100. let {
  101. declaration
  102. } = stmt.node;
  103. let varId;
  104. if (_core.types.isClassDeclaration(declaration)) {
  105. varId = declaration.id;
  106. declaration.id = _core.types.cloneNode(varId);
  107. declaration = _core.types.toExpression(declaration);
  108. } else if (!_core.types.isExpression(declaration)) {
  109. continue;
  110. }
  111. varId != null ? varId : varId = path.scope.generateUidIdentifier("_default");
  112. innerBlockBody.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(varId, declaration)]));
  113. stmt.replaceWith(_core.types.exportNamedDeclaration(null, [_core.types.exportSpecifier(_core.types.cloneNode(varId), _core.types.identifier("default"))]));
  114. continue;
  115. }
  116. if (stmt.isExportNamedDeclaration()) {
  117. node = stmt.node.declaration;
  118. if (!node || _core.types.isFunction(node)) continue;
  119. stmt.replaceWith(_core.types.exportNamedDeclaration(null, Object.keys(_core.types.getOuterBindingIdentifiers(node, false)).map(id => _core.types.exportSpecifier(_core.types.identifier(id), _core.types.identifier(id)))));
  120. shouldRemove = false;
  121. } else if (stmt.isExportDeclaration()) {
  122. continue;
  123. }
  124. if (_core.types.isClassDeclaration(node)) {
  125. const {
  126. id
  127. } = node;
  128. node.id = _core.types.cloneNode(id);
  129. innerBlockBody.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(id, _core.types.toExpression(node))]));
  130. } else if (_core.types.isVariableDeclaration(node)) {
  131. if (node.kind === "using") {
  132. TOP_LEVEL_USING.set(stmt.node, 0);
  133. } else if (node.kind === "await using") {
  134. TOP_LEVEL_USING.set(stmt.node, 1);
  135. }
  136. node.kind = "var";
  137. innerBlockBody.push(node);
  138. } else {
  139. innerBlockBody.push(stmt.node);
  140. }
  141. if (shouldRemove) stmt.remove();
  142. }
  143. path.pushContainer("body", _core.types.blockStatement(innerBlockBody));
  144. },
  145. Function(path, state) {
  146. if (path.node.async) {
  147. path.traverse(transformUsingDeclarationsVisitorSkipFn, state);
  148. }
  149. }
  150. }])
  151. };
  152. });
  153. //# sourceMappingURL=index.js.map