Skip to content

Commit 6d24076

Browse files
authoredApr 15, 2024··
fix(es/proposal): Update explicit resource management to match spec (#8860)
**Related issue:** - Closes #8853
1 parent 3de8253 commit 6d24076

File tree

26 files changed

+404
-160
lines changed

26 files changed

+404
-160
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
function _using_ctx() {
2+
var _disposeSuppressedError =
3+
typeof SuppressedError === "function"
4+
? // eslint-disable-next-line no-undef
5+
SuppressedError
6+
: (function (error, suppressed) {
7+
var err = new Error();
8+
err.name = "SuppressedError";
9+
err.suppressed = suppressed;
10+
err.error = error;
11+
return err;
12+
}),
13+
empty = {},
14+
stack = [];
15+
function using(isAwait, value) {
16+
if (value != null) {
17+
if (Object(value) !== value) {
18+
throw new TypeError(
19+
"using declarations can only be used with objects, functions, null, or undefined.",
20+
);
21+
}
22+
// core-js-pure uses Symbol.for for polyfilling well-known symbols
23+
if (isAwait) {
24+
var dispose =
25+
value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
26+
}
27+
if (dispose == null) {
28+
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
29+
}
30+
if (typeof dispose !== "function") {
31+
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
32+
}
33+
stack.push({ v: value, d: dispose, a: isAwait });
34+
} else if (isAwait) {
35+
// provide the nullish `value` as `d` for minification gain
36+
stack.push({ d: value, a: isAwait });
37+
}
38+
return value;
39+
}
40+
return {
41+
// error
42+
e: empty,
43+
// using
44+
u: using.bind(null, false),
45+
// await using
46+
a: using.bind(null, true),
47+
// dispose
48+
d: function () {
49+
var error = this.e;
50+
51+
function next() {
52+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
53+
while ((resource = stack.pop())) {
54+
try {
55+
var resource,
56+
disposalResult = resource.d && resource.d.call(resource.v);
57+
if (resource.a) {
58+
return Promise.resolve(disposalResult).then(next, err);
59+
}
60+
} catch (e) {
61+
return err(e);
62+
}
63+
}
64+
if (error !== empty) throw error;
65+
}
66+
67+
function err(e) {
68+
error = error !== empty ? new _disposeSuppressedError(error, e) : e;
69+
70+
return next();
71+
}
72+
73+
return next();
74+
},
75+
};
76+
}

‎crates/swc_ecma_transforms_base/src/helpers/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ define_helpers!(Helpers {
384384
identity: (),
385385
dispose: (),
386386
using: (),
387+
using_ctx: (),
387388
});
388389

389390
pub fn inject_helpers(global_mark: Mark) -> impl Fold + VisitMut {

‎crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs

+42-54
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use std::iter::once;
2-
31
use swc_common::{util::take::Take, DUMMY_SP};
42
use swc_ecma_ast::*;
53
use swc_ecma_transforms_base::helper;
6-
use swc_ecma_utils::{find_pat_ids, private_ident, ExprFactory, ModuleItemLike, StmtLike};
4+
use swc_ecma_utils::{
5+
find_pat_ids, private_ident, quote_ident, ExprFactory, ModuleItemLike, StmtLike,
6+
};
77
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
88

99
pub fn explicit_resource_management() -> impl Fold + VisitMut {
@@ -18,9 +18,7 @@ struct ExplicitResourceManagement {
1818
}
1919

2020
struct State {
21-
stack: Ident,
22-
has_error: Ident,
23-
error_var: Ident,
21+
using_ctx: Ident,
2422
catch_var: Ident,
2523

2624
has_await: bool,
@@ -29,9 +27,7 @@ struct State {
2927
impl Default for State {
3028
fn default() -> Self {
3129
Self {
32-
stack: private_ident!("_stack"),
33-
has_error: private_ident!("_hasError"),
34-
error_var: private_ident!("_error"),
30+
using_ctx: private_ident!("_usingCtx"),
3531
catch_var: private_ident!("_"),
3632
has_await: false,
3733
}
@@ -63,13 +59,15 @@ impl ExplicitResourceManagement {
6359
let mut extras = vec![];
6460
let mut try_body = vec![];
6561

66-
let stack_var_decl = VarDeclarator {
62+
let using_ctx_var = VarDeclarator {
6763
span: DUMMY_SP,
68-
name: state.stack.clone().into(),
64+
name: state.using_ctx.clone().into(),
6965
init: Some(
70-
ArrayLit {
66+
CallExpr {
67+
callee: helper!(using_ctx),
7168
span: DUMMY_SP,
72-
elems: vec![],
69+
args: Default::default(),
70+
type_args: Default::default(),
7371
}
7472
.into(),
7573
),
@@ -80,16 +78,16 @@ impl ExplicitResourceManagement {
8078
span: DUMMY_SP,
8179
kind: VarDeclKind::Var,
8280
declare: false,
83-
decls: vec![stack_var_decl],
81+
decls: vec![using_ctx_var],
8482
}))));
8583

8684
for stmt in stmts.take() {
8785
match stmt.try_into_stmt() {
8886
Ok(stmt @ Stmt::Decl(Decl::Fn(..))) => {
8987
new.push(T::from_stmt(stmt));
9088
}
91-
Ok(Stmt::Decl(Decl::Var(mut var))) => {
92-
var.kind = VarDeclKind::Var;
89+
Ok(Stmt::Decl(Decl::Var(var))) => {
90+
// var.kind = VarDeclKind::Var;
9391
try_body.push(Stmt::Decl(Decl::Var(var)));
9492
}
9593
Ok(stmt) => try_body.push(stmt),
@@ -310,39 +308,28 @@ impl ExplicitResourceManagement {
310308
// Drop `;`
311309
try_body.retain(|stmt| !matches!(stmt, Stmt::Empty(..)));
312310

313-
// var error = $catch_var
314-
let error_catch_var = Stmt::Decl(Decl::Var(Box::new(VarDecl {
315-
span: DUMMY_SP,
316-
kind: VarDeclKind::Var,
317-
declare: false,
318-
decls: vec![VarDeclarator {
319-
span: DUMMY_SP,
320-
name: state.error_var.clone().into(),
321-
init: Some(state.catch_var.clone().into()),
322-
definite: false,
323-
}],
324-
})));
325-
326-
// var has_error = true
327-
let has_error_true = Stmt::Decl(Decl::Var(Box::new(VarDecl {
311+
// usingCtx.e = $catch_var
312+
let assign_error = AssignExpr {
328313
span: DUMMY_SP,
329-
kind: VarDeclKind::Var,
330-
declare: false,
331-
decls: vec![VarDeclarator {
332-
span: DUMMY_SP,
333-
name: state.has_error.clone().into(),
334-
init: Some(true.into()),
335-
definite: false,
336-
}],
337-
})));
314+
op: op!("="),
315+
left: state
316+
.using_ctx
317+
.clone()
318+
.make_member(quote_ident!("e"))
319+
.into(),
320+
right: state.catch_var.clone().into(),
321+
}
322+
.into_stmt();
323+
324+
// _usingCtx.d()
338325
let dispose_expr = CallExpr {
339326
span: DUMMY_SP,
340-
callee: helper!(dispose),
341-
args: vec![
342-
state.stack.as_arg(),
343-
state.error_var.as_arg(),
344-
state.has_error.as_arg(),
345-
],
327+
callee: state
328+
.using_ctx
329+
.clone()
330+
.make_member(quote_ident!("d"))
331+
.as_callee(),
332+
args: vec![],
346333
type_args: Default::default(),
347334
};
348335
let dispose_stmt = if state.has_await {
@@ -366,7 +353,7 @@ impl ExplicitResourceManagement {
366353
param: Some(state.catch_var.into()),
367354
body: BlockStmt {
368355
span: DUMMY_SP,
369-
stmts: vec![error_catch_var, has_error_true],
356+
stmts: vec![assign_error],
370357
},
371358
}),
372359
finalizer: Some(BlockStmt {
@@ -434,15 +421,16 @@ impl VisitMut for ExplicitResourceManagement {
434421
.map(|d| {
435422
let init = CallExpr {
436423
span: decl.span,
437-
callee: helper!(using),
438-
args: once(state.stack.clone().as_arg())
439-
.chain(once(d.init.unwrap().as_arg()))
440-
.chain(if decl.is_await {
441-
Some(true.as_arg())
424+
callee: state
425+
.using_ctx
426+
.clone()
427+
.make_member(if decl.is_await {
428+
quote_ident!("a")
442429
} else {
443-
None
430+
quote_ident!("u")
444431
})
445-
.collect(),
432+
.as_callee(),
433+
args: vec![d.init.unwrap().as_arg()],
446434
type_args: Default::default(),
447435
};
448436

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const { deepStrictEqual } = require('node:assert')
2+
3+
let i = 0
4+
let err
5+
try {
6+
await using _x1 = {
7+
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
8+
throw [1, ++i]
9+
}
10+
}
11+
12+
await using _x2 = {
13+
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
14+
throw [2, ++i]
15+
}
16+
}
17+
18+
await using _x3 = {
19+
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
20+
throw [3, ++i]
21+
}
22+
}
23+
24+
await using _x4 = {
25+
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
26+
throw [4, ++i]
27+
}
28+
}
29+
30+
throw [5, ++i]
31+
} catch (e) {
32+
err = e
33+
}
34+
35+
console.log(err)
36+
deepStrictEqual(err.suppressed, [1, 5])
37+
deepStrictEqual(err.error.suppressed, [2, 4])
38+
deepStrictEqual(err.error.error.suppressed, [3, 3])
39+
deepStrictEqual(err.error.error.error.suppressed, [4, 2])
40+
deepStrictEqual(err.error.error.error.error, [5, 1])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
let i = 0
3+
let err
4+
try {
5+
await using _x1 = {
6+
async [Symbol.asyncDispose]() {
7+
throw [1, ++i]
8+
}
9+
}
10+
11+
await using _x2 = {
12+
async [Symbol.asyncDispose]() {
13+
throw [2, ++i]
14+
}
15+
}
16+
17+
await using _x3 = {
18+
async [Symbol.asyncDispose]() {
19+
throw [3, ++i]
20+
}
21+
}
22+
23+
await using _x4 = {
24+
async [Symbol.asyncDispose]() {
25+
throw [4, ++i]
26+
}
27+
}
28+
29+
throw [5, ++i]
30+
} catch (e) {
31+
err = e
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
let i = 0;
2+
let err;
3+
try {
4+
try {
5+
var _usingCtx = _using_ctx();
6+
const _x1 = _usingCtx.a({
7+
async [Symbol.asyncDispose] () {
8+
throw [
9+
1,
10+
++i
11+
];
12+
}
13+
});
14+
const _x2 = _usingCtx.a({
15+
async [Symbol.asyncDispose] () {
16+
throw [
17+
2,
18+
++i
19+
];
20+
}
21+
});
22+
const _x3 = _usingCtx.a({
23+
async [Symbol.asyncDispose] () {
24+
throw [
25+
3,
26+
++i
27+
];
28+
}
29+
});
30+
const _x4 = _usingCtx.a({
31+
async [Symbol.asyncDispose] () {
32+
throw [
33+
4,
34+
++i
35+
];
36+
}
37+
});
38+
throw [
39+
5,
40+
++i
41+
];
42+
} catch (_) {
43+
_usingCtx.e = _;
44+
} finally{
45+
await _usingCtx.d();
46+
}
47+
} catch (e) {
48+
err = e;
49+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
try {
3-
var _stack = [];
4-
var a = _using(_stack, 1);
5-
var b = _using(_stack, 2, true);
6-
var c = _using(_stack, 3);
3+
var _usingCtx = _using_ctx();
4+
const a = _usingCtx.u(1);
5+
const b = _usingCtx.a(2);
6+
const c = _usingCtx.u(3);
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
await _dispose(_stack, _error, _hasError);
10+
await _usingCtx.d();
1211
}
1312
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
{
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, obj, true);
3+
var _usingCtx = _using_ctx();
4+
const x = _usingCtx.a(obj);
55
stmt;
6-
var y = _using(_stack, obj, true), z = _using(_stack, obj, true);
6+
const y = _usingCtx.a(obj), z = _usingCtx.a(obj);
77
doSomethingWith(x, y);
88
} catch (_) {
9-
var _error = _;
10-
var _hasError = true;
9+
_usingCtx.e = _;
1110
} finally{
12-
await _dispose(_stack, _error, _hasError);
11+
await _usingCtx.d();
1312
}
1413
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
{
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, obj);
3+
var _usingCtx = _using_ctx();
4+
const x = _usingCtx.u(obj);
55
doSomethingWith(x);
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}
1211
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
for await (const x of y){
22
try {
3-
var _stack = [];
3+
var _usingCtx = _using_ctx();
44
{
55
doSomethingWith(x);
66
}
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
_dispose(_stack, _error, _hasError);
10+
_usingCtx.d();
1211
}
1312
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
for (const x of y){
22
try {
3-
var _stack = [];
3+
var _usingCtx = _using_ctx();
44
{
55
doSomethingWith(x);
66
}
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
_dispose(_stack, _error, _hasError);
10+
_usingCtx.d();
1211
}
1312
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
function fn() {
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, obj);
3+
var _usingCtx = _using_ctx();
4+
const x = _usingCtx.u(obj);
55
return doSomethingWith(x);
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}
1211
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
if (test) {
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, obj);
3+
var _usingCtx = _using_ctx();
4+
const x = _usingCtx.u(obj);
55
doSomethingWith(x);
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}
1211
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
// main.ts
22
var _Disposable;
33
try {
4-
var _stack = [];
4+
var _usingCtx = _using_ctx();
55
class Disposable {
66
[Symbol.dispose]() {
77
console.log('dispose');
88
}
99
}
1010
_Disposable = Disposable;
11-
var _disposable = _using(_stack, new Disposable());
11+
var _disposable = _usingCtx.u(new Disposable());
1212
console.log('ok');
1313
} catch (_) {
14-
var _error = _;
15-
var _hasError = true;
14+
_usingCtx.e = _;
1615
} finally{
17-
_dispose(_stack, _error, _hasError);
16+
_usingCtx.d();
1817
}
1918
export { _Disposable as Disposable };
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,32 @@
11
{
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, obj);
3+
var _usingCtx = _using_ctx();
4+
const x = _usingCtx.u(obj);
55
{
66
try {
7-
var _stack1 = [];
8-
var y = _using(_stack1, call(()=>{
7+
var _usingCtx1 = _using_ctx();
8+
const y = _usingCtx1.u(call(()=>{
99
try {
10-
var _stack = [];
11-
var z = _using(_stack, obj);
10+
var _usingCtx = _using_ctx();
11+
const z = _usingCtx.u(obj);
1212
return z;
1313
} catch (_) {
14-
var _error = _;
15-
var _hasError = true;
14+
_usingCtx.e = _;
1615
} finally{
17-
_dispose(_stack, _error, _hasError);
16+
_usingCtx.d();
1817
}
1918
}));
2019
stmt;
2120
} catch (_) {
22-
var _error = _;
23-
var _hasError = true;
21+
_usingCtx1.e = _;
2422
} finally{
25-
_dispose(_stack1, _error, _hasError);
23+
_usingCtx1.d();
2624
}
2725
}
2826
stmt;
2927
} catch (_) {
30-
var _error1 = _;
31-
var _hasError1 = true;
28+
_usingCtx.e = _;
3229
} finally{
33-
_dispose(_stack, _error1, _hasError1);
30+
_usingCtx.d();
3431
}
3532
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
{
22
try {
3-
var _stack = [];
3+
var _usingCtx = _using_ctx();
44
stmt;
5-
var x = _using(_stack, obj);
5+
const x = _usingCtx.u(obj);
66
stmt;
7-
var y = _using(_stack, obj), z = _using(_stack, obj);
7+
const y = _usingCtx.u(obj), z = _usingCtx.u(obj);
88
stmt;
9-
var w = _using(_stack, obj);
9+
const w = _usingCtx.u(obj);
1010
doSomethingWith(x, z);
1111
} catch (_) {
12-
var _error = _;
13-
var _hasError = true;
12+
_usingCtx.e = _;
1413
} finally{
15-
_dispose(_stack, _error, _hasError);
14+
_usingCtx.d();
1615
}
1716
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
class A {
22
static{
33
try {
4-
var _stack = [];
5-
var x = _using(_stack, y);
4+
var _usingCtx = _using_ctx();
5+
const x = _usingCtx.u(y);
66
doSomethingWith(x);
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
_dispose(_stack, _error, _hasError);
10+
_usingCtx.d();
1211
}
1312
}
1413
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
export { x, y };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, A);
5-
var y = _using(_stack, B, true);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(A);
5+
var y = _usingCtx.a(B);
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
await _dispose(_stack, _error, _hasError);
9+
await _usingCtx.d();
1110
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
export { _default as default };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, null);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(null);
55
var _default = class {
66
};
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
_dispose(_stack, _error, _hasError);
10+
_usingCtx.d();
1211
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
export { C as default };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, null);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(null);
55
var C = class C {
66
};
77
} catch (_) {
8-
var _error = _;
9-
var _hasError = true;
8+
_usingCtx.e = _;
109
} finally{
11-
_dispose(_stack, _error, _hasError);
10+
_usingCtx.d();
1211
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
export { _default as default };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, null);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(null);
55
var _default = doSomething();
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
export { fn as default };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, null);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(null);
55
var fn = function fn() {};
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
export { fn as default };
22
try {
3-
var _stack = [];
4-
var x = _using(_stack, null);
3+
var _usingCtx = _using_ctx();
4+
var x = _usingCtx.u(null);
55
var fn = function fn() {};
66
} catch (_) {
7-
var _error = _;
8-
var _hasError = true;
7+
_usingCtx.e = _;
98
} finally{
10-
_dispose(_stack, _error, _hasError);
9+
_usingCtx.d();
1110
}

‎crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting/output.mjs

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,25 @@ export { f };
1414
var _b;
1515
var _B;
1616
try {
17-
var _stack = [];
17+
var _usingCtx = _using_ctx();
1818
function g() {
1919
c;
2020
}
2121
_g = g;
2222
doSomething();
2323
let { b } = {};
2424
_b = b;
25-
var c = 2;
25+
let c = 2;
2626
class A {
2727
}
2828
class B {
2929
}
3030
_B = B;
31-
var x = _using(_stack, null);
31+
var x = _usingCtx.u(null);
3232
} catch (_) {
33-
var _error = _;
34-
var _hasError = true;
33+
_usingCtx.e = _;
3534
} finally{
36-
_dispose(_stack, _error, _hasError);
35+
_usingCtx.d();
3736
}
3837
export { _g as g };
3938
export { _b as b };

‎packages/helpers/esm/_using_ctx.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
export function _usingCtx() {
2+
var _disposeSuppressedError =
3+
typeof SuppressedError === "function"
4+
? // eslint-disable-next-line no-undef
5+
SuppressedError
6+
: (function (error, suppressed) {
7+
var err = new Error();
8+
err.name = "SuppressedError";
9+
err.suppressed = suppressed;
10+
err.error = error;
11+
return err;
12+
}),
13+
empty = {},
14+
stack = [];
15+
function using(isAwait, value) {
16+
if (value != null) {
17+
if (Object(value) !== value) {
18+
throw new TypeError(
19+
"using declarations can only be used with objects, functions, null, or undefined.",
20+
);
21+
}
22+
// core-js-pure uses Symbol.for for polyfilling well-known symbols
23+
if (isAwait) {
24+
var dispose =
25+
value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
26+
}
27+
if (dispose == null) {
28+
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
29+
}
30+
if (typeof dispose !== "function") {
31+
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
32+
}
33+
stack.push({ v: value, d: dispose, a: isAwait });
34+
} else if (isAwait) {
35+
// provide the nullish `value` as `d` for minification gain
36+
stack.push({ d: value, a: isAwait });
37+
}
38+
return value;
39+
}
40+
return {
41+
// error
42+
e: empty,
43+
// using
44+
u: using.bind(null, false),
45+
// await using
46+
a: using.bind(null, true),
47+
// dispose
48+
d: function () {
49+
var error = this.e;
50+
51+
function next() {
52+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
53+
while ((resource = stack.pop())) {
54+
try {
55+
var resource,
56+
disposalResult = resource.d && resource.d.call(resource.v);
57+
if (resource.a) {
58+
return Promise.resolve(disposalResult).then(next, err);
59+
}
60+
} catch (e) {
61+
return err(e);
62+
}
63+
}
64+
if (error !== empty) throw error;
65+
}
66+
67+
function err(e) {
68+
error = error !== empty ? new _disposeSuppressedError(error, e) : e;
69+
70+
return next();
71+
}
72+
73+
return next();
74+
},
75+
};
76+
}
77+
78+
export { _usingCtx as _ }

‎packages/helpers/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@swc/helpers",
33
"packageManager": "yarn@4.0.2",
4-
"version": "0.5.9",
4+
"version": "0.5.10",
55
"description": "External helpers for the swc project.",
66
"module": "esm/index.js",
77
"main": "cjs/index.cjs",

0 commit comments

Comments
 (0)
Please sign in to comment.