Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(es/compat): Implement transform for explicit resource management #7376

Merged
merged 68 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
f164917
Add a test
kdy1 May 11, 2023
ebc1193
More work
kdy1 May 11, 2023
fed116f
test
kdy1 May 11, 2023
dffab9f
test_fixture
kdy1 May 11, 2023
cf3bdbb
Add tests
kdy1 Jun 20, 2023
4df3c9c
Rename
kdy1 Jun 20, 2023
3ccc155
output path
kdy1 Jun 20, 2023
cc066ce
Fix path
kdy1 Jun 20, 2023
df0c3a3
Typo
kdy1 Jun 20, 2023
83e22df
mjs
kdy1 Jun 20, 2023
262e96f
exec
kdy1 Jun 20, 2023
62ca46e
test name
kdy1 Jun 20, 2023
0a4489b
`await_`
kdy1 Jun 20, 2023
d2a5479
Fix visitor
kdy1 Jun 20, 2023
ba73363
`is_await`
kdy1 Jun 20, 2023
fe5f1d8
fixup
kdy1 Jun 20, 2023
088cd13
await
kdy1 Jun 20, 2023
be84c8f
serde
kdy1 Jun 20, 2023
93c5e5b
Fix quote
kdy1 Jun 20, 2023
028c537
`visit_mut_stmt_likes`
kdy1 Jun 27, 2023
9bbaf40
codegen
kdy1 Jun 27, 2023
0bffa0d
More
kdy1 Jun 27, 2023
7f2e857
WIP
kdy1 Jun 27, 2023
69f71d4
helper
kdy1 Jun 29, 2023
f05664f
try
kdy1 Jun 29, 2023
95823f4
_using
kdy1 Jun 29, 2023
8810c61
using
kdy1 Jun 29, 2023
7d37526
sort
kdy1 Jun 29, 2023
0cdb779
Prevent overflow
kdy1 Jun 29, 2023
e0b9c99
stack var
kdy1 Jun 29, 2023
694cd7b
await using
kdy1 Jun 29, 2023
16ab2b1
await
kdy1 Jun 29, 2023
18831f0
Var decl
kdy1 Jun 29, 2023
11bf306
input.mjs
kdy1 Jun 29, 2023
5e5bcd2
`allow_using_decl`
kdy1 Jun 29, 2023
f839993
`allow_using_decl`
kdy1 Jun 29, 2023
a220dda
Drop `;`
kdy1 Jun 29, 2023
2018855
fixup: doc
kdy1 Jun 29, 2023
e98c211
await dispose
kdy1 Jun 29, 2023
fd8e906
is_await
kdy1 Jun 29, 2023
533fb3e
order
kdy1 Jun 29, 2023
566ee08
Update test refs
kdy1 Jun 29, 2023
0a4365d
const
kdy1 Jun 29, 2023
7c1060e
Update test refs
kdy1 Jun 29, 2023
fa0c57a
Update test refs
kdy1 Jun 29, 2023
7c96a55
Ignore
kdy1 Jun 29, 2023
16a7411
Update test refs
kdy1 Jun 29, 2023
c562a1e
external helpers
kdy1 Jun 29, 2023
0e068e1
Update test refs
kdy1 Jun 29, 2023
f5761be
Update test refs
kdy1 Jun 29, 2023
e5b404b
Fix parser
kdy1 Jun 29, 2023
0cda26a
`use_const`
kdy1 Jun 29, 2023
12a393a
Update test refs
kdy1 Jun 29, 2023
3f7ecfa
for of
kdy1 Jun 29, 2023
faee8e7
fixup
kdy1 Jun 29, 2023
059a37e
Update test refs
kdy1 Jun 29, 2023
a733502
Rename
kdy1 Jun 29, 2023
35a6b5c
hoist
kdy1 Jun 29, 2023
98999aa
export default decl
kdy1 Jun 29, 2023
fe2aabf
Update test refs
kdy1 Jun 29, 2023
9139151
export default expr
kdy1 Jun 29, 2023
7349008
Update test refs
kdy1 Jun 29, 2023
6806fd2
Update test refs
kdy1 Jun 29, 2023
b771a14
_
kdy1 Jun 29, 2023
1ad03e6
Fix helpers
kdy1 Jun 29, 2023
2e59114
Merge branch 'main' into erm-transform
swc-bot Jun 29, 2023
29f8b58
Merge branch 'main' into erm-transform
swc-bot Jun 29, 2023
23b739d
Ignore
kdy1 Jun 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut};

pub fn explicit_resource_management() -> impl Fold + VisitMut {
as_folder(ExplicitResourceManagement)
}

struct ExplicitResourceManagement;

impl VisitMut for ExplicitResourceManagement {
noop_visit_mut_type!();
}
1 change: 1 addition & 0 deletions crates/swc_ecma_transforms_proposal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub use self::{

pub mod decorator_2022_03;
pub mod decorators;
pub mod explicit_resource_management;
mod export_default_from;
mod import_assertions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
return async function () {
let disposed = false;
let beforeEnd;

const err1 = {};
const err2 = {};
let thrown;

try {
await using x = {
[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
throw err1;
}
};
throw err2;
} catch (e) {
thrown = e;
}

expect(thrown.suppressed).toBe(err1);
expect(thrown.error).toBe(err2);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
return async function () {
let disposed = false;
let beforeBreak;

while (true) {
await using x = {
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
disposed = true;
}
};
beforeBreak = disposed;
break;
}

expect(beforeBreak).toBe(false);
expect(disposed).toBe(true);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
return async function () {
let disposed = false;
let beforeEnd;

{
await using x = {
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
disposed = true;
}
};
beforeEnd = disposed;
}

expect(beforeEnd).toBe(false);
expect(disposed).toBe(true);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
return async function () {
let disposed = false;
let beforeReturn;

await async function () {
await using x = {
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
disposed = true;
}
};
beforeReturn = disposed;
return 0;
}();

expect(beforeReturn).toBe(false);
expect(disposed).toBe(true);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
return async function () {
let disposed = false;
let beforeReturn;
let inCatch;
let inFinally;

try {
await using x = {
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
disposed = true;
}
};
beforeReturn = disposed;
throw 0;
} catch {
inCatch = disposed;
}

expect(beforeReturn).toBe(false);
expect(inCatch).toBe(true);
expect(disposed).toBe(true);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
return expect(async function () {
await using foo = { [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]: 3 };
}()).rejects.toThrow(TypeError);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
return async function () {
let log = [];

function disposable(name){
return {
async [Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")]() {
log.push(name);
}
};
}

{
await using x = disposable("x");
await using y = disposable("y"), z = disposable("z");
await using w = disposable("w");
log.push("body");
}

expect(log).toEqual(["body", "w", "z", "y", "x"]);
}();
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": [
"proposal-explicit-resource-management",
"transform-optional-catch-binding",
"transform-async-to-generator"
],
"parserOpts": { "allowReturnOutsideFunction": true }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
return (async function () {
let log = [];

function disposable(name, symbolName, cb){
return {
async [Symbol[symbolName] || Symbol.for("Symbol." + symbolName)]() {
log.push(name);
if (cb) cb();
}
};
}

let inBmicrotick = false;
let inBmicrotickWhileC = false;
let inBmicrotickWhileD = false;
let inBmicrotickWhileE = false;
{
using e = disposable("e", "dispose", () => {
inBmicrotickWhileE = inBmicrotick;
});
await using d = disposable("d", "asyncDispose", () => {
inBmicrotickWhileD = inBmicrotick;
});
using c = disposable("c", "dispose", () => {
inBmicrotickWhileC = inBmicrotick;
});
using b = disposable("b", "dispose", () => {
inBmicrotick = true;
Promise.resolve().then(() => {
inBmicrotick = false;
});
});
await using a = disposable("a", "asyncDispose");
}

expect(log).toEqual(["a", "b", "c", "d", "e"]);
expect(inBmicrotick).toBe(false);
expect(inBmicrotickWhileC).toBe(true);
expect(inBmicrotickWhileD).toBe(true);
expect(inBmicrotickWhileE).toBe(false);
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
return (async function () {
let disposed = false;
let awaited = false;
let beforeEnd;
{
await using x = {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
disposed = true;
}
};
beforeEnd = disposed;
Promise.resolve().then(() => {
awaited = true;
});
}

expect(beforeEnd).toBe(false);
expect(disposed).toBe(true);
expect(awaited).toBe(true);
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
return expect(async function () {
await using x = null;
}()).resolves.toBeUndefined();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
let disposed = false;
let beforeBreak;

while (true) {
using x = {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
disposed = true;
}
};
beforeBreak = disposed;
break;
}

expect(beforeBreak).toBe(false);
expect(disposed).toBe(true);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
let disposed = false;
let beforeEnd;

{
using x = {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
disposed = true;
}
};
beforeEnd = disposed;
}

expect(beforeEnd).toBe(false);
expect(disposed).toBe(true);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
let disposed = false;
let beforeReturn;

(function () {
using x = {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
disposed = true;
}
};
beforeReturn = disposed;
return 0;
})();

expect(beforeReturn).toBe(false);
expect(disposed).toBe(true);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
let disposed = false;
let beforeReturn;
let inCatch;
let inFinally;

try {
using x = {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
disposed = true;
}
};
beforeReturn = disposed;
throw 0;
} catch {
inCatch = disposed;
}

expect(beforeReturn).toBe(false);
expect(inCatch).toBe(true);
expect(disposed).toBe(true);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
expect(() => {
using foo = { [Symbol.dispose || Symbol.for("Symbol.dispose")]: 3 };
}).toThrow(TypeError);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
expect(() => {
using x = 2;
}).toThrow(TypeError);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
let log = [];

function disposable(name){
return {
[Symbol.dispose || Symbol.for("Symbol.dispose")]() {
log.push(name);
}
};
}

{
using x = disposable("x");
using y = disposable("y"), z = disposable("z");
using w = disposable("w");
log.push("body");
}

expect(log).toEqual(["body", "w", "z", "y", "x"]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"plugins": [
"proposal-explicit-resource-management",
"transform-optional-catch-binding"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
expect(() => {
using x = null;
using y = undefined;
}).not.toThrow();
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
async function fn() {
await 0;
{
await using x = y;
await 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"plugins": [
"proposal-explicit-resource-management",
"transform-async-to-generator"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function fn() {
return _fn.apply(this, arguments);
}
function _fn() {
_fn = babelHelpers.asyncToGenerator(function* () {
yield 0;
try {
var _stack = [];
const x = babelHelpers.using(_stack, y, true);
yield 1;
} catch (_) {
var _error = _;
var _hasError = true;
} finally {
yield babelHelpers.dispose(_stack, _error, _hasError);
}
});
return _fn.apply(this, arguments);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-explicit-resource-management"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
using a = 1;
await using b = 2;
using c = 3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
try {
var _stack = [];
const a = babelHelpers.using(_stack, 1);
const b = babelHelpers.using(_stack, 2, true);
const c = babelHelpers.using(_stack, 3);
} catch (_) {
var _error = _;
var _hasError = true;
} finally {
await babelHelpers.dispose(_stack, _error, _hasError);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
await using x = obj;
stmt;
await using y = obj, z = obj;
doSomethingWith(x, y);
}