From 94c3bf4ce9d62bbf2be1273cc773a61079aea501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Odin=20H=C3=B8rthe-Omdal=20Urdland?= Date: Mon, 4 Dec 2023 15:19:12 +0100 Subject: [PATCH] using: Allow looking up 'Symbol.dispose' on a function --- packages/babel-helpers/src/helpers-generated.ts | 2 +- packages/babel-helpers/src/helpers/using.js | 4 ++-- .../test/fixtures/exec-async/using-function.js | 15 +++++++++++++++ .../test/fixtures/exec-sync/using-function.js | 10 ++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/using-function.js create mode 100644 packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-sync/using-function.js diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index fc0ddce43989..7c04a333f440 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -111,7 +111,7 @@ export default Object.freeze({ ), using: helper( "7.22.0", - 'export default function _using(o,e,n){if(null==e)return e;if("object"!=typeof e)throw new TypeError("using declarations can only be used with objects, null, or undefined.");if(n)var r=e[Symbol.asyncDispose||Symbol.for("Symbol.asyncDispose")];if(null==r&&(r=e[Symbol.dispose||Symbol.for("Symbol.dispose")]),"function"!=typeof r)throw new TypeError("Property [Symbol.dispose] is not a function.");return o.push({v:e,d:r,a:n}),e}', + 'export default function _using(o,n,e){if(null==n)return n;if(Object(n)!==n)throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");if(e)var r=n[Symbol.asyncDispose||Symbol.for("Symbol.asyncDispose")];if(null==r&&(r=n[Symbol.dispose||Symbol.for("Symbol.dispose")]),"function"!=typeof r)throw new TypeError("Property [Symbol.dispose] is not a function.");return o.push({v:n,d:r,a:e}),n}', ), wrapRegExp: helper( "7.19.0", diff --git a/packages/babel-helpers/src/helpers/using.js b/packages/babel-helpers/src/helpers/using.js index 6f2348ac5755..ce9bdb1ef4b0 100644 --- a/packages/babel-helpers/src/helpers/using.js +++ b/packages/babel-helpers/src/helpers/using.js @@ -2,9 +2,9 @@ export default function _using(stack, value, isAwait) { if (value === null || value === void 0) return value; - if (typeof value !== "object") { + if (Object(value) !== value) { throw new TypeError( - "using declarations can only be used with objects, null, or undefined." + "using declarations can only be used with objects, functions, null, or undefined." ); } // core-js-pure uses Symbol.for for polyfilling well-known symbols diff --git a/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/using-function.js b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/using-function.js new file mode 100644 index 000000000000..75a8be647881 --- /dev/null +++ b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-async/using-function.js @@ -0,0 +1,15 @@ +return async function () { + let log = []; + async function getDisposable() { + function disposable() { log.push('call') } + disposable[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")] = () => { log.push('dispose') }; + return disposable; + } + + { + await using x = getDisposable(); + x(); + } + + expect(log).toEqual(['call', 'dispose']); +} diff --git a/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-sync/using-function.js b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-sync/using-function.js new file mode 100644 index 000000000000..70bf43ec5117 --- /dev/null +++ b/packages/babel-plugin-proposal-explicit-resource-management/test/fixtures/exec-sync/using-function.js @@ -0,0 +1,10 @@ +let log = []; +function disposable() { log.push('call') } +disposable[Symbol.dispose || Symbol.for("Symbol.dispose")] = () => { log.push('dispose') }; + +{ + using x = disposable; + x(); +} + +expect(log).toEqual(['call', 'dispose']);