mirror of
https://github.com/swc-project/swc.git
synced 2024-11-29 22:51:38 +03:00
fix(es/proposal): Update explicit resource management to match spec (#8860)
**Related issue:** - Closes #8853
This commit is contained in:
parent
3de82531b2
commit
6d240768b1
76
crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js
Normal file
76
crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js
Normal file
@ -0,0 +1,76 @@
|
||||
function _using_ctx() {
|
||||
var _disposeSuppressedError =
|
||||
typeof SuppressedError === "function"
|
||||
? // eslint-disable-next-line no-undef
|
||||
SuppressedError
|
||||
: (function (error, suppressed) {
|
||||
var err = new Error();
|
||||
err.name = "SuppressedError";
|
||||
err.suppressed = suppressed;
|
||||
err.error = error;
|
||||
return err;
|
||||
}),
|
||||
empty = {},
|
||||
stack = [];
|
||||
function using(isAwait, value) {
|
||||
if (value != null) {
|
||||
if (Object(value) !== value) {
|
||||
throw new TypeError(
|
||||
"using declarations can only be used with objects, functions, null, or undefined.",
|
||||
);
|
||||
}
|
||||
// core-js-pure uses Symbol.for for polyfilling well-known symbols
|
||||
if (isAwait) {
|
||||
var dispose =
|
||||
value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
|
||||
}
|
||||
if (dispose == null) {
|
||||
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
|
||||
}
|
||||
if (typeof dispose !== "function") {
|
||||
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
|
||||
}
|
||||
stack.push({ v: value, d: dispose, a: isAwait });
|
||||
} else if (isAwait) {
|
||||
// provide the nullish `value` as `d` for minification gain
|
||||
stack.push({ d: value, a: isAwait });
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
// error
|
||||
e: empty,
|
||||
// using
|
||||
u: using.bind(null, false),
|
||||
// await using
|
||||
a: using.bind(null, true),
|
||||
// dispose
|
||||
d: function () {
|
||||
var error = this.e;
|
||||
|
||||
function next() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
while ((resource = stack.pop())) {
|
||||
try {
|
||||
var resource,
|
||||
disposalResult = resource.d && resource.d.call(resource.v);
|
||||
if (resource.a) {
|
||||
return Promise.resolve(disposalResult).then(next, err);
|
||||
}
|
||||
} catch (e) {
|
||||
return err(e);
|
||||
}
|
||||
}
|
||||
if (error !== empty) throw error;
|
||||
}
|
||||
|
||||
function err(e) {
|
||||
error = error !== empty ? new _disposeSuppressedError(error, e) : e;
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
return next();
|
||||
},
|
||||
};
|
||||
}
|
@ -384,6 +384,7 @@ define_helpers!(Helpers {
|
||||
identity: (),
|
||||
dispose: (),
|
||||
using: (),
|
||||
using_ctx: (),
|
||||
});
|
||||
|
||||
pub fn inject_helpers(global_mark: Mark) -> impl Fold + VisitMut {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::iter::once;
|
||||
|
||||
use swc_common::{util::take::Take, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms_base::helper;
|
||||
use swc_ecma_utils::{find_pat_ids, private_ident, ExprFactory, ModuleItemLike, StmtLike};
|
||||
use swc_ecma_utils::{
|
||||
find_pat_ids, private_ident, quote_ident, ExprFactory, ModuleItemLike, StmtLike,
|
||||
};
|
||||
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
|
||||
|
||||
pub fn explicit_resource_management() -> impl Fold + VisitMut {
|
||||
@ -18,9 +18,7 @@ struct ExplicitResourceManagement {
|
||||
}
|
||||
|
||||
struct State {
|
||||
stack: Ident,
|
||||
has_error: Ident,
|
||||
error_var: Ident,
|
||||
using_ctx: Ident,
|
||||
catch_var: Ident,
|
||||
|
||||
has_await: bool,
|
||||
@ -29,9 +27,7 @@ struct State {
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
stack: private_ident!("_stack"),
|
||||
has_error: private_ident!("_hasError"),
|
||||
error_var: private_ident!("_error"),
|
||||
using_ctx: private_ident!("_usingCtx"),
|
||||
catch_var: private_ident!("_"),
|
||||
has_await: false,
|
||||
}
|
||||
@ -63,13 +59,15 @@ impl ExplicitResourceManagement {
|
||||
let mut extras = vec![];
|
||||
let mut try_body = vec![];
|
||||
|
||||
let stack_var_decl = VarDeclarator {
|
||||
let using_ctx_var = VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: state.stack.clone().into(),
|
||||
name: state.using_ctx.clone().into(),
|
||||
init: Some(
|
||||
ArrayLit {
|
||||
CallExpr {
|
||||
callee: helper!(using_ctx),
|
||||
span: DUMMY_SP,
|
||||
elems: vec![],
|
||||
args: Default::default(),
|
||||
type_args: Default::default(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
@ -80,7 +78,7 @@ impl ExplicitResourceManagement {
|
||||
span: DUMMY_SP,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![stack_var_decl],
|
||||
decls: vec![using_ctx_var],
|
||||
}))));
|
||||
|
||||
for stmt in stmts.take() {
|
||||
@ -88,8 +86,8 @@ impl ExplicitResourceManagement {
|
||||
Ok(stmt @ Stmt::Decl(Decl::Fn(..))) => {
|
||||
new.push(T::from_stmt(stmt));
|
||||
}
|
||||
Ok(Stmt::Decl(Decl::Var(mut var))) => {
|
||||
var.kind = VarDeclKind::Var;
|
||||
Ok(Stmt::Decl(Decl::Var(var))) => {
|
||||
// var.kind = VarDeclKind::Var;
|
||||
try_body.push(Stmt::Decl(Decl::Var(var)));
|
||||
}
|
||||
Ok(stmt) => try_body.push(stmt),
|
||||
@ -310,39 +308,28 @@ impl ExplicitResourceManagement {
|
||||
// Drop `;`
|
||||
try_body.retain(|stmt| !matches!(stmt, Stmt::Empty(..)));
|
||||
|
||||
// var error = $catch_var
|
||||
let error_catch_var = Stmt::Decl(Decl::Var(Box::new(VarDecl {
|
||||
// usingCtx.e = $catch_var
|
||||
let assign_error = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: state.error_var.clone().into(),
|
||||
init: Some(state.catch_var.clone().into()),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
op: op!("="),
|
||||
left: state
|
||||
.using_ctx
|
||||
.clone()
|
||||
.make_member(quote_ident!("e"))
|
||||
.into(),
|
||||
right: state.catch_var.clone().into(),
|
||||
}
|
||||
.into_stmt();
|
||||
|
||||
// var has_error = true
|
||||
let has_error_true = Stmt::Decl(Decl::Var(Box::new(VarDecl {
|
||||
span: DUMMY_SP,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: state.has_error.clone().into(),
|
||||
init: Some(true.into()),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
// _usingCtx.d()
|
||||
let dispose_expr = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(dispose),
|
||||
args: vec![
|
||||
state.stack.as_arg(),
|
||||
state.error_var.as_arg(),
|
||||
state.has_error.as_arg(),
|
||||
],
|
||||
callee: state
|
||||
.using_ctx
|
||||
.clone()
|
||||
.make_member(quote_ident!("d"))
|
||||
.as_callee(),
|
||||
args: vec![],
|
||||
type_args: Default::default(),
|
||||
};
|
||||
let dispose_stmt = if state.has_await {
|
||||
@ -366,7 +353,7 @@ impl ExplicitResourceManagement {
|
||||
param: Some(state.catch_var.into()),
|
||||
body: BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
stmts: vec![error_catch_var, has_error_true],
|
||||
stmts: vec![assign_error],
|
||||
},
|
||||
}),
|
||||
finalizer: Some(BlockStmt {
|
||||
@ -434,15 +421,16 @@ impl VisitMut for ExplicitResourceManagement {
|
||||
.map(|d| {
|
||||
let init = CallExpr {
|
||||
span: decl.span,
|
||||
callee: helper!(using),
|
||||
args: once(state.stack.clone().as_arg())
|
||||
.chain(once(d.init.unwrap().as_arg()))
|
||||
.chain(if decl.is_await {
|
||||
Some(true.as_arg())
|
||||
callee: state
|
||||
.using_ctx
|
||||
.clone()
|
||||
.make_member(if decl.is_await {
|
||||
quote_ident!("a")
|
||||
} else {
|
||||
None
|
||||
quote_ident!("u")
|
||||
})
|
||||
.collect(),
|
||||
.as_callee(),
|
||||
args: vec![d.init.unwrap().as_arg()],
|
||||
type_args: Default::default(),
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
const { deepStrictEqual } = require('node:assert')
|
||||
|
||||
let i = 0
|
||||
let err
|
||||
try {
|
||||
await using _x1 = {
|
||||
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
|
||||
throw [1, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x2 = {
|
||||
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
|
||||
throw [2, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x3 = {
|
||||
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
|
||||
throw [3, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x4 = {
|
||||
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
|
||||
throw [4, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
throw [5, ++i]
|
||||
} catch (e) {
|
||||
err = e
|
||||
}
|
||||
|
||||
console.log(err)
|
||||
deepStrictEqual(err.suppressed, [1, 5])
|
||||
deepStrictEqual(err.error.suppressed, [2, 4])
|
||||
deepStrictEqual(err.error.error.suppressed, [3, 3])
|
||||
deepStrictEqual(err.error.error.error.suppressed, [4, 2])
|
||||
deepStrictEqual(err.error.error.error.error, [5, 1])
|
@ -0,0 +1,32 @@
|
||||
|
||||
let i = 0
|
||||
let err
|
||||
try {
|
||||
await using _x1 = {
|
||||
async [Symbol.asyncDispose]() {
|
||||
throw [1, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x2 = {
|
||||
async [Symbol.asyncDispose]() {
|
||||
throw [2, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x3 = {
|
||||
async [Symbol.asyncDispose]() {
|
||||
throw [3, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
await using _x4 = {
|
||||
async [Symbol.asyncDispose]() {
|
||||
throw [4, ++i]
|
||||
}
|
||||
}
|
||||
|
||||
throw [5, ++i]
|
||||
} catch (e) {
|
||||
err = e
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
let i = 0;
|
||||
let err;
|
||||
try {
|
||||
try {
|
||||
var _usingCtx = _using_ctx();
|
||||
const _x1 = _usingCtx.a({
|
||||
async [Symbol.asyncDispose] () {
|
||||
throw [
|
||||
1,
|
||||
++i
|
||||
];
|
||||
}
|
||||
});
|
||||
const _x2 = _usingCtx.a({
|
||||
async [Symbol.asyncDispose] () {
|
||||
throw [
|
||||
2,
|
||||
++i
|
||||
];
|
||||
}
|
||||
});
|
||||
const _x3 = _usingCtx.a({
|
||||
async [Symbol.asyncDispose] () {
|
||||
throw [
|
||||
3,
|
||||
++i
|
||||
];
|
||||
}
|
||||
});
|
||||
const _x4 = _usingCtx.a({
|
||||
async [Symbol.asyncDispose] () {
|
||||
throw [
|
||||
4,
|
||||
++i
|
||||
];
|
||||
}
|
||||
});
|
||||
throw [
|
||||
5,
|
||||
++i
|
||||
];
|
||||
} catch (_) {
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
await _usingCtx.d();
|
||||
}
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
{
|
||||
try {
|
||||
var _stack = [];
|
||||
var a = _using(_stack, 1);
|
||||
var b = _using(_stack, 2, true);
|
||||
var c = _using(_stack, 3);
|
||||
var _usingCtx = _using_ctx();
|
||||
const a = _usingCtx.u(1);
|
||||
const b = _usingCtx.a(2);
|
||||
const c = _usingCtx.u(3);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
await _dispose(_stack, _error, _hasError);
|
||||
await _usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
{
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, obj, true);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.a(obj);
|
||||
stmt;
|
||||
var y = _using(_stack, obj, true), z = _using(_stack, obj, true);
|
||||
const y = _usingCtx.a(obj), z = _usingCtx.a(obj);
|
||||
doSomethingWith(x, y);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
await _dispose(_stack, _error, _hasError);
|
||||
await _usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
{
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, obj);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.u(obj);
|
||||
doSomethingWith(x);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
for await (const x of y){
|
||||
try {
|
||||
var _stack = [];
|
||||
var _usingCtx = _using_ctx();
|
||||
{
|
||||
doSomethingWith(x);
|
||||
}
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
for (const x of y){
|
||||
try {
|
||||
var _stack = [];
|
||||
var _usingCtx = _using_ctx();
|
||||
{
|
||||
doSomethingWith(x);
|
||||
}
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
function fn() {
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, obj);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.u(obj);
|
||||
return doSomethingWith(x);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
if (test) {
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, obj);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.u(obj);
|
||||
doSomethingWith(x);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
// main.ts
|
||||
var _Disposable;
|
||||
try {
|
||||
var _stack = [];
|
||||
var _usingCtx = _using_ctx();
|
||||
class Disposable {
|
||||
[Symbol.dispose]() {
|
||||
console.log('dispose');
|
||||
}
|
||||
}
|
||||
_Disposable = Disposable;
|
||||
var _disposable = _using(_stack, new Disposable());
|
||||
var _disposable = _usingCtx.u(new Disposable());
|
||||
console.log('ok');
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
export { _Disposable as Disposable };
|
||||
|
@ -1,35 +1,32 @@
|
||||
{
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, obj);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.u(obj);
|
||||
{
|
||||
try {
|
||||
var _stack1 = [];
|
||||
var y = _using(_stack1, call(()=>{
|
||||
var _usingCtx1 = _using_ctx();
|
||||
const y = _usingCtx1.u(call(()=>{
|
||||
try {
|
||||
var _stack = [];
|
||||
var z = _using(_stack, obj);
|
||||
var _usingCtx = _using_ctx();
|
||||
const z = _usingCtx.u(obj);
|
||||
return z;
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}));
|
||||
stmt;
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx1.e = _;
|
||||
} finally{
|
||||
_dispose(_stack1, _error, _hasError);
|
||||
_usingCtx1.d();
|
||||
}
|
||||
}
|
||||
stmt;
|
||||
} catch (_) {
|
||||
var _error1 = _;
|
||||
var _hasError1 = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error1, _hasError1);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
{
|
||||
try {
|
||||
var _stack = [];
|
||||
var _usingCtx = _using_ctx();
|
||||
stmt;
|
||||
var x = _using(_stack, obj);
|
||||
const x = _usingCtx.u(obj);
|
||||
stmt;
|
||||
var y = _using(_stack, obj), z = _using(_stack, obj);
|
||||
const y = _usingCtx.u(obj), z = _usingCtx.u(obj);
|
||||
stmt;
|
||||
var w = _using(_stack, obj);
|
||||
const w = _usingCtx.u(obj);
|
||||
doSomethingWith(x, z);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
class A {
|
||||
static{
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, y);
|
||||
var _usingCtx = _using_ctx();
|
||||
const x = _usingCtx.u(y);
|
||||
doSomethingWith(x);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
export { x, y };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, A);
|
||||
var y = _using(_stack, B, true);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(A);
|
||||
var y = _usingCtx.a(B);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
await _dispose(_stack, _error, _hasError);
|
||||
await _usingCtx.d();
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
export { _default as default };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, null);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(null);
|
||||
var _default = class {
|
||||
};
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
export { C as default };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, null);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(null);
|
||||
var C = class C {
|
||||
};
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
export { _default as default };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, null);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(null);
|
||||
var _default = doSomething();
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
export { fn as default };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, null);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(null);
|
||||
var fn = function fn() {};
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
export { fn as default };
|
||||
try {
|
||||
var _stack = [];
|
||||
var x = _using(_stack, null);
|
||||
var _usingCtx = _using_ctx();
|
||||
var x = _usingCtx.u(null);
|
||||
var fn = function fn() {};
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export { f };
|
||||
var _b;
|
||||
var _B;
|
||||
try {
|
||||
var _stack = [];
|
||||
var _usingCtx = _using_ctx();
|
||||
function g() {
|
||||
c;
|
||||
}
|
||||
@ -22,18 +22,17 @@ try {
|
||||
doSomething();
|
||||
let { b } = {};
|
||||
_b = b;
|
||||
var c = 2;
|
||||
let c = 2;
|
||||
class A {
|
||||
}
|
||||
class B {
|
||||
}
|
||||
_B = B;
|
||||
var x = _using(_stack, null);
|
||||
var x = _usingCtx.u(null);
|
||||
} catch (_) {
|
||||
var _error = _;
|
||||
var _hasError = true;
|
||||
_usingCtx.e = _;
|
||||
} finally{
|
||||
_dispose(_stack, _error, _hasError);
|
||||
_usingCtx.d();
|
||||
}
|
||||
export { _g as g };
|
||||
export { _b as b };
|
||||
|
78
packages/helpers/esm/_using_ctx.js
Normal file
78
packages/helpers/esm/_using_ctx.js
Normal file
@ -0,0 +1,78 @@
|
||||
export function _usingCtx() {
|
||||
var _disposeSuppressedError =
|
||||
typeof SuppressedError === "function"
|
||||
? // eslint-disable-next-line no-undef
|
||||
SuppressedError
|
||||
: (function (error, suppressed) {
|
||||
var err = new Error();
|
||||
err.name = "SuppressedError";
|
||||
err.suppressed = suppressed;
|
||||
err.error = error;
|
||||
return err;
|
||||
}),
|
||||
empty = {},
|
||||
stack = [];
|
||||
function using(isAwait, value) {
|
||||
if (value != null) {
|
||||
if (Object(value) !== value) {
|
||||
throw new TypeError(
|
||||
"using declarations can only be used with objects, functions, null, or undefined.",
|
||||
);
|
||||
}
|
||||
// core-js-pure uses Symbol.for for polyfilling well-known symbols
|
||||
if (isAwait) {
|
||||
var dispose =
|
||||
value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
|
||||
}
|
||||
if (dispose == null) {
|
||||
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
|
||||
}
|
||||
if (typeof dispose !== "function") {
|
||||
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
|
||||
}
|
||||
stack.push({ v: value, d: dispose, a: isAwait });
|
||||
} else if (isAwait) {
|
||||
// provide the nullish `value` as `d` for minification gain
|
||||
stack.push({ d: value, a: isAwait });
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
// error
|
||||
e: empty,
|
||||
// using
|
||||
u: using.bind(null, false),
|
||||
// await using
|
||||
a: using.bind(null, true),
|
||||
// dispose
|
||||
d: function () {
|
||||
var error = this.e;
|
||||
|
||||
function next() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
while ((resource = stack.pop())) {
|
||||
try {
|
||||
var resource,
|
||||
disposalResult = resource.d && resource.d.call(resource.v);
|
||||
if (resource.a) {
|
||||
return Promise.resolve(disposalResult).then(next, err);
|
||||
}
|
||||
} catch (e) {
|
||||
return err(e);
|
||||
}
|
||||
}
|
||||
if (error !== empty) throw error;
|
||||
}
|
||||
|
||||
function err(e) {
|
||||
error = error !== empty ? new _disposeSuppressedError(error, e) : e;
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
return next();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export { _usingCtx as _ }
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@swc/helpers",
|
||||
"packageManager": "yarn@4.0.2",
|
||||
"version": "0.5.9",
|
||||
"version": "0.5.10",
|
||||
"description": "External helpers for the swc project.",
|
||||
"module": "esm/index.js",
|
||||
"main": "cjs/index.cjs",
|
||||
|
Loading…
Reference in New Issue
Block a user