You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
6.7 KiB
155 lines
6.7 KiB
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
var _helperPluginUtils = require("@babel/helper-plugin-utils");
|
|
var _pluginTransformDestructuring = require("@babel/plugin-transform-destructuring");
|
|
var _core = require("@babel/core");
|
|
function isAnonymousFunctionDefinition(node) {
|
|
return _core.types.isArrowFunctionExpression(node) || (_core.types.isFunctionExpression(node) || _core.types.isClassExpression(node)) && !node.id;
|
|
}
|
|
function emitSetFunctionNameCall(state, expression, name) {
|
|
return _core.types.callExpression(state.addHelper("setFunctionName"), [expression, _core.types.stringLiteral(name)]);
|
|
}
|
|
var _default = exports.default = (0, _helperPluginUtils.declare)(api => {
|
|
api.assertVersion("^7.23.9 || >8.0.0-alpha <8.0.0-beta");
|
|
const TOP_LEVEL_USING = new Map();
|
|
function isUsingDeclaration(node) {
|
|
if (!_core.types.isVariableDeclaration(node)) return false;
|
|
return node.kind === "using" || node.kind === "await using" || TOP_LEVEL_USING.has(node);
|
|
}
|
|
const transformUsingDeclarationsVisitor = {
|
|
ForOfStatement(path) {
|
|
const {
|
|
left
|
|
} = path.node;
|
|
if (!isUsingDeclaration(left)) return;
|
|
const {
|
|
id
|
|
} = left.declarations[0];
|
|
const tmpId = path.scope.generateUidIdentifierBasedOnNode(id);
|
|
left.declarations[0].id = tmpId;
|
|
left.kind = "const";
|
|
path.ensureBlock();
|
|
(0, _pluginTransformDestructuring.unshiftForXStatementBody)(path, [_core.types.variableDeclaration("using", [_core.types.variableDeclarator(id, _core.types.cloneNode(tmpId))])]);
|
|
},
|
|
"BlockStatement|StaticBlock"(path, state) {
|
|
let ctx = null;
|
|
let needsAwait = false;
|
|
const scope = path.scope;
|
|
for (const node of path.node.body) {
|
|
if (!isUsingDeclaration(node)) continue;
|
|
ctx != null ? ctx : ctx = scope.generateUidIdentifier("usingCtx");
|
|
const isAwaitUsing = node.kind === "await using" || TOP_LEVEL_USING.get(node) === 1;
|
|
needsAwait || (needsAwait = isAwaitUsing);
|
|
if (!TOP_LEVEL_USING.delete(node)) {
|
|
node.kind = "const";
|
|
}
|
|
for (const decl of node.declarations) {
|
|
const currentInit = decl.init;
|
|
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]);
|
|
}
|
|
}
|
|
if (!ctx) return;
|
|
const disposeCall = _core.types.callExpression(_core.types.memberExpression(_core.types.cloneNode(ctx), _core.types.identifier("d")), []);
|
|
const replacement = _core.template.statement.ast`
|
|
try {
|
|
var ${_core.types.cloneNode(ctx)} = ${state.addHelper("usingCtx")}();
|
|
${path.node.body}
|
|
} catch (_) {
|
|
${_core.types.cloneNode(ctx)}.e = _;
|
|
} finally {
|
|
${needsAwait ? _core.types.awaitExpression(disposeCall) : disposeCall}
|
|
}
|
|
`;
|
|
_core.types.inherits(replacement, path.node);
|
|
const {
|
|
parentPath
|
|
} = path;
|
|
if (parentPath.isFunction() || parentPath.isTryStatement() || parentPath.isCatchClause()) {
|
|
path.replaceWith(_core.types.blockStatement([replacement]));
|
|
} else if (path.isStaticBlock()) {
|
|
path.node.body = [replacement];
|
|
} else {
|
|
path.replaceWith(replacement);
|
|
}
|
|
}
|
|
};
|
|
const transformUsingDeclarationsVisitorSkipFn = _core.traverse.visitors.merge([transformUsingDeclarationsVisitor, {
|
|
Function(path) {
|
|
path.skip();
|
|
}
|
|
}]);
|
|
return {
|
|
name: "transform-explicit-resource-management",
|
|
manipulateOptions: (_, p) => p.plugins.push("explicitResourceManagement"),
|
|
visitor: _core.traverse.visitors.merge([transformUsingDeclarationsVisitor, {
|
|
Program(path) {
|
|
TOP_LEVEL_USING.clear();
|
|
if (path.node.sourceType !== "module") return;
|
|
if (!path.node.body.some(isUsingDeclaration)) return;
|
|
const innerBlockBody = [];
|
|
for (const stmt of path.get("body")) {
|
|
if (stmt.isFunctionDeclaration() || stmt.isImportDeclaration()) {
|
|
continue;
|
|
}
|
|
let node = stmt.node;
|
|
let shouldRemove = true;
|
|
if (stmt.isExportDefaultDeclaration()) {
|
|
let {
|
|
declaration
|
|
} = stmt.node;
|
|
let varId;
|
|
if (_core.types.isClassDeclaration(declaration)) {
|
|
varId = declaration.id;
|
|
declaration.id = _core.types.cloneNode(varId);
|
|
declaration = _core.types.toExpression(declaration);
|
|
} else if (!_core.types.isExpression(declaration)) {
|
|
continue;
|
|
}
|
|
varId != null ? varId : varId = path.scope.generateUidIdentifier("_default");
|
|
innerBlockBody.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(varId, declaration)]));
|
|
stmt.replaceWith(_core.types.exportNamedDeclaration(null, [_core.types.exportSpecifier(_core.types.cloneNode(varId), _core.types.identifier("default"))]));
|
|
continue;
|
|
}
|
|
if (stmt.isExportNamedDeclaration()) {
|
|
node = stmt.node.declaration;
|
|
if (!node || _core.types.isFunction(node)) continue;
|
|
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)))));
|
|
shouldRemove = false;
|
|
} else if (stmt.isExportDeclaration()) {
|
|
continue;
|
|
}
|
|
if (_core.types.isClassDeclaration(node)) {
|
|
const {
|
|
id
|
|
} = node;
|
|
node.id = _core.types.cloneNode(id);
|
|
innerBlockBody.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(id, _core.types.toExpression(node))]));
|
|
} else if (_core.types.isVariableDeclaration(node)) {
|
|
if (node.kind === "using") {
|
|
TOP_LEVEL_USING.set(stmt.node, 0);
|
|
} else if (node.kind === "await using") {
|
|
TOP_LEVEL_USING.set(stmt.node, 1);
|
|
}
|
|
node.kind = "var";
|
|
innerBlockBody.push(node);
|
|
} else {
|
|
innerBlockBody.push(stmt.node);
|
|
}
|
|
if (shouldRemove) stmt.remove();
|
|
}
|
|
path.pushContainer("body", _core.types.blockStatement(innerBlockBody));
|
|
},
|
|
Function(path, state) {
|
|
if (path.node.async) {
|
|
path.traverse(transformUsingDeclarationsVisitorSkipFn, state);
|
|
}
|
|
}
|
|
}])
|
|
};
|
|
});
|
|
|
|
//# sourceMappingURL=index.js.map
|
|
|