From c3e61b5945e0af2aa2bdd23c42479c6b1961bd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:11:09 +0900 Subject: [PATCH 01/15] Add a test --- .../exec-async/issue-8853.js | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js new file mode 100644 index 000000000000..942806052fbf --- /dev/null +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js @@ -0,0 +1,40 @@ +import { deepStrictEqual } from 'node:assert' +import process from 'node:process' + +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 +} + +deepStrictEqual(err.error, 1) +deepStrictEqual(err.suppressed.error, 2) +deepStrictEqual(err.suppressed.suppressed.error, 3) +deepStrictEqual(err.suppressed.suppressed.suppressed.error, 4) +deepStrictEqual(err.suppressed.suppressed.suppressed.suppressed, 5) \ No newline at end of file From d317af13f98bfb60d4122d8c6953c9f84b11bad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:16:58 +0900 Subject: [PATCH 02/15] fixup --- .../explicit-resource-management/exec-async/issue-8853.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js index 942806052fbf..4b6039063762 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js @@ -1,5 +1,4 @@ -import { deepStrictEqual } from 'node:assert' -import process from 'node:process' +const { deepStrictEqual } = require('node:assert') let i = 0 let err From 8a1b30df30b4a06250d512e1e5e3b1c794b0dafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:19:31 +0900 Subject: [PATCH 03/15] Add a test using babel --- .../transform-await/issue-8853/input.mjs | 32 +++++++++++++++++ .../transform-await/issue-8853/output.mjs | 34 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/input.mjs create mode 100644 crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/input.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/input.mjs new file mode 100644 index 000000000000..88d6474578a1 --- /dev/null +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/input.mjs @@ -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 +} \ No newline at end of file diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs new file mode 100644 index 000000000000..450dcf64ab31 --- /dev/null +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs @@ -0,0 +1,34 @@ +let i = 0; +let err; +try { + try { + var _usingCtx = _usingCtx2(); + 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; +} \ No newline at end of file From 730768c7e48f7a8702979c1898e872bb3ed0e73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:24:05 +0900 Subject: [PATCH 04/15] helper --- .../src/helpers/_using_ctx.js | 76 ++++++++++++++++++ packages/helpers/esm/_using_ctx.js | 78 +++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js create mode 100644 packages/helpers/esm/_using_ctx.js diff --git a/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js b/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js new file mode 100644 index 000000000000..d3b149c8d58b --- /dev/null +++ b/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js @@ -0,0 +1,76 @@ +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(); + }, + }; +} \ No newline at end of file diff --git a/packages/helpers/esm/_using_ctx.js b/packages/helpers/esm/_using_ctx.js new file mode 100644 index 000000000000..76e6d86e83b9 --- /dev/null +++ b/packages/helpers/esm/_using_ctx.js @@ -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 _ } \ No newline at end of file From d9498d46beab9280fe26217e6b7750c68fa7ad47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:24:19 +0900 Subject: [PATCH 05/15] bump helpers --- packages/helpers/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/helpers/package.json b/packages/helpers/package.json index c637a26d182a..986f160c433c 100644 --- a/packages/helpers/package.json +++ b/packages/helpers/package.json @@ -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", From 77012ef1d2eedeb27580aea7bca82c214936b5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:24:42 +0900 Subject: [PATCH 06/15] fixup --- crates/swc_ecma_transforms_base/src/helpers/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/swc_ecma_transforms_base/src/helpers/mod.rs b/crates/swc_ecma_transforms_base/src/helpers/mod.rs index ed966b27e2d9..691fddef79ce 100644 --- a/crates/swc_ecma_transforms_base/src/helpers/mod.rs +++ b/crates/swc_ecma_transforms_base/src/helpers/mod.rs @@ -384,6 +384,7 @@ define_helpers!(Helpers { identity: (), dispose: (), using: (), + using_ctx: (), }); pub fn inject_helpers(global_mark: Mark) -> impl Fold + VisitMut { From cd6fb6a8d559271aba74393e862b9bb74bacd213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:32:20 +0900 Subject: [PATCH 07/15] field --- .../src/explicit_resource_management.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index 625c03b91cf4..1aa04cae2d9f 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -18,10 +18,7 @@ struct ExplicitResourceManagement { } struct State { - stack: Ident, - has_error: Ident, - error_var: Ident, - catch_var: Ident, + using_ctx: Ident, has_await: bool, } @@ -29,10 +26,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"), - catch_var: private_ident!("_"), + using_ctx: private_ident!("_usingCtx"), has_await: false, } } From 55fd73786ec37fa915b910bfa295bcdb78ad7bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:36:20 +0900 Subject: [PATCH 08/15] var usingCtx --- .../src/explicit_resource_management.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index 1aa04cae2d9f..56b79174138f 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -2,7 +2,7 @@ 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_transforms_base::{helper, helper_expr}; use swc_ecma_utils::{find_pat_ids, private_ident, ExprFactory, ModuleItemLike, StmtLike}; use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}; @@ -57,13 +57,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(), ), @@ -74,7 +76,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() { From 3c667e92a933e44cfd5ed86d4efe97ca826dd117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:38:24 +0900 Subject: [PATCH 09/15] usingCtx.a --- .../src/explicit_resource_management.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index 56b79174138f..04b954a1344b 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -3,7 +3,9 @@ use std::iter::once; use swc_common::{util::take::Take, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_transforms_base::{helper, helper_expr}; -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 { @@ -430,9 +432,12 @@ 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())) + callee: state + .using_ctx + .clone() + .make_member(quote_ident!("a")) + .as_callee(), + args: once(d.init.unwrap().as_arg()) .chain(if decl.is_await { Some(true.as_arg()) } else { From 596224481edea2d42d33dc87f9fb2864d93384b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:43:52 +0900 Subject: [PATCH 10/15] fix --- .../src/explicit_resource_management.rs | 67 +++++++------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index 04b954a1344b..ed65aaadfe75 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -2,7 +2,7 @@ use std::iter::once; use swc_common::{util::take::Take, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_transforms_base::{helper, helper_expr}; +use swc_ecma_transforms_base::helper; use swc_ecma_utils::{ find_pat_ids, private_ident, quote_ident, ExprFactory, ModuleItemLike, StmtLike, }; @@ -21,6 +21,7 @@ struct ExplicitResourceManagement { struct State { using_ctx: Ident, + catch_var: Ident, has_await: bool, } @@ -29,6 +30,7 @@ impl Default for State { fn default() -> Self { Self { using_ctx: private_ident!("_usingCtx"), + catch_var: private_ident!("_"), has_await: false, } } @@ -86,8 +88,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), @@ -308,39 +310,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, - }], - }))); - - // 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, - }], - }))); + op: op!("="), + left: state + .using_ctx + .clone() + .make_member(quote_ident!("e")) + .into(), + right: state.catch_var.clone().into(), + } + .into_stmt(); + + // _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 { @@ -364,7 +355,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 { @@ -437,13 +428,7 @@ impl VisitMut for ExplicitResourceManagement { .clone() .make_member(quote_ident!("a")) .as_callee(), - args: once(d.init.unwrap().as_arg()) - .chain(if decl.is_await { - Some(true.as_arg()) - } else { - None - }) - .collect(), + args: vec![d.init.unwrap().as_arg()], type_args: Default::default(), }; From bc2f78eba620bf0ec9f2d8bb23688ac961d7e81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:43:59 +0900 Subject: [PATCH 11/15] lint --- .../src/explicit_resource_management.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index ed65aaadfe75..ba5f033f0d79 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -1,5 +1,3 @@ -use std::iter::once; - use swc_common::{util::take::Take, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_transforms_base::helper; From 9da3a5f91d872bec2c1e08700ccfe08e696fe483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:47:28 +0900 Subject: [PATCH 12/15] Fix helper --- crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js b/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js index d3b149c8d58b..5076a16cd877 100644 --- a/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js +++ b/crates/swc_ecma_transforms_base/src/helpers/_using_ctx.js @@ -1,4 +1,4 @@ -function _usingCtx() { +function _using_ctx() { var _disposeSuppressedError = typeof SuppressedError === "function" ? // eslint-disable-next-line no-undef From beea3acfce4aea25ac99fdd104c8e0d7b5a092eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:49:34 +0900 Subject: [PATCH 13/15] async/sync --- .../src/explicit_resource_management.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs index ba5f033f0d79..5dbc11d28f70 100644 --- a/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs +++ b/crates/swc_ecma_transforms_proposal/src/explicit_resource_management.rs @@ -424,7 +424,11 @@ impl VisitMut for ExplicitResourceManagement { callee: state .using_ctx .clone() - .make_member(quote_ident!("a")) + .make_member(if decl.is_await { + quote_ident!("a") + } else { + quote_ident!("u") + }) .as_callee(), args: vec![d.init.unwrap().as_arg()], type_args: Default::default(), From 05b17dfddd23a9c816aceea109e655256b618fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 13:49:47 +0900 Subject: [PATCH 14/15] Update test refs --- .../transform-await/issue-8853/output.mjs | 39 +++++++++++++------ .../transform-await/mixed/output.mjs | 13 +++---- .../only-using-await/output.mjs | 11 +++--- .../transform-sync/bare-block/output.js | 9 ++--- .../transform-sync/for-await-head/output.mjs | 7 ++-- .../transform-sync/for-head/output.js | 7 ++-- .../transform-sync/function-body/output.js | 9 ++--- .../transform-sync/if-body/output.js | 9 ++--- .../transform-sync/issue-8629/output.js | 9 ++--- .../transform-sync/multiple-nested/output.js | 27 ++++++------- .../multiple-same-level/output.js | 13 +++---- .../transform-sync/static-block/output.js | 9 ++--- .../await-or-not-preserved/output.mjs | 11 +++--- .../hoisting-default-clas-anon/output.mjs | 9 ++--- .../hoisting-default-class/output.mjs | 9 ++--- .../hoisting-default-expr/output.mjs | 9 ++--- .../hoisting-default-fn-anon/output.mjs | 9 ++--- .../hoisting-default-fn/output.mjs | 9 ++--- .../transform-top-level/hoisting/output.mjs | 11 +++--- 19 files changed, 112 insertions(+), 117 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs index 450dcf64ab31..7d8080129a94 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/issue-8853/output.mjs @@ -2,33 +2,48 @@ let i = 0; let err; try { try { - var _usingCtx = _usingCtx2(); + var _usingCtx = _using_ctx(); const _x1 = _usingCtx.a({ - async [Symbol.asyncDispose]() { - throw [1, ++i]; + async [Symbol.asyncDispose] () { + throw [ + 1, + ++i + ]; } }); const _x2 = _usingCtx.a({ - async [Symbol.asyncDispose]() { - throw [2, ++i]; + async [Symbol.asyncDispose] () { + throw [ + 2, + ++i + ]; } }); const _x3 = _usingCtx.a({ - async [Symbol.asyncDispose]() { - throw [3, ++i]; + async [Symbol.asyncDispose] () { + throw [ + 3, + ++i + ]; } }); const _x4 = _usingCtx.a({ - async [Symbol.asyncDispose]() { - throw [4, ++i]; + async [Symbol.asyncDispose] () { + throw [ + 4, + ++i + ]; } }); - throw [5, ++i]; + throw [ + 5, + ++i + ]; } catch (_) { _usingCtx.e = _; - } finally { + } finally{ await _usingCtx.d(); } } catch (e) { err = e; -} \ No newline at end of file +} diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/mixed/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/mixed/output.mjs index 6f2b7f937492..bc88967b14d5 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/mixed/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/mixed/output.mjs @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/only-using-await/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/only-using-await/output.mjs index 5d4390b9ffbe..ab8caf7f5d1e 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/only-using-await/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-await/only-using-await/output.mjs @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/bare-block/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/bare-block/output.js index 6982b489b611..ae57c226afa8 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/bare-block/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/bare-block/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-await-head/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-await-head/output.mjs index 64e1f0205047..69d1662c66a6 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-await-head/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-await-head/output.mjs @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-head/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-head/output.js index 11e7a96f20a0..664ad9129e5e 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-head/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/for-head/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/function-body/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/function-body/output.js index 4330fb187b30..73a4f9acebd4 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/function-body/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/function-body/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/if-body/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/if-body/output.js index 41666e989ff9..37a67bf08873 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/if-body/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/if-body/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/issue-8629/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/issue-8629/output.js index 71f3493adabe..f4bf134efc46 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/issue-8629/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/issue-8629/output.js @@ -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 }; diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-nested/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-nested/output.js index 84cc09b386a1..a43a642ea82b 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-nested/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-nested/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-same-level/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-same-level/output.js index 8ac894590485..74d1135cdc3f 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-same-level/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/multiple-same-level/output.js @@ -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(); } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/static-block/output.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/static-block/output.js index cec9c08fbe4e..40822b4ddd8f 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/static-block/output.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-sync/static-block/output.js @@ -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(); } } } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/await-or-not-preserved/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/await-or-not-preserved/output.mjs index 1e0a43605140..95ff79d27880 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/await-or-not-preserved/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/await-or-not-preserved/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-clas-anon/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-clas-anon/output.mjs index ece84ba9eeb6..92818dd6f95f 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-clas-anon/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-clas-anon/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-class/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-class/output.mjs index c71d8b9c7953..34ad7a56f1df 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-class/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-class/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-expr/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-expr/output.mjs index 8a2ecaa8ac0d..682561df4403 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-expr/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-expr/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn-anon/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn-anon/output.mjs index ebbc6014dd8c..7357daba7ddf 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn-anon/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn-anon/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn/output.mjs index ebbc6014dd8c..7357daba7ddf 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting-default-fn/output.mjs @@ -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(); } diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting/output.mjs b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting/output.mjs index c4b66aaf50b7..022a0f510e9d 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting/output.mjs +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/transform-top-level/hoisting/output.mjs @@ -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 }; From 38da21f5ccc877150c2b3d7b192c710bc46c5e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Mon, 15 Apr 2024 14:01:22 +0900 Subject: [PATCH 15/15] fix input --- .../exec-async/issue-8853.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js index 4b6039063762..5876957eb2f1 100644 --- a/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js +++ b/crates/swc_ecma_transforms_proposal/tests/explicit-resource-management/exec-async/issue-8853.js @@ -4,25 +4,25 @@ let i = 0 let err try { await using _x1 = { - async [Symbol.asyncDispose]() { + async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() { throw [1, ++i] } } await using _x2 = { - async [Symbol.asyncDispose]() { + async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() { throw [2, ++i] } } await using _x3 = { - async [Symbol.asyncDispose]() { + async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() { throw [3, ++i] } } await using _x4 = { - async [Symbol.asyncDispose]() { + async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() { throw [4, ++i] } } @@ -32,8 +32,9 @@ try { err = e } -deepStrictEqual(err.error, 1) -deepStrictEqual(err.suppressed.error, 2) -deepStrictEqual(err.suppressed.suppressed.error, 3) -deepStrictEqual(err.suppressed.suppressed.suppressed.error, 4) -deepStrictEqual(err.suppressed.suppressed.suppressed.suppressed, 5) \ No newline at end of file +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]) \ No newline at end of file