From 21e14787c521cc1f808c9b71e8671820a79bd12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 20 Jan 2023 17:50:51 +0900 Subject: [PATCH] fix(es/minifier): Don't inline into `await` from sequential inliner (#6839) **Related issue:** - Closes https://github.com/swc-project/swc/issues/6837. --- .../fixture/issues-6xxx/6729/output/index.js | 9 ++-- .../src/compress/optimize/sequences.rs | 8 +++- .../tests/fixture/issues/6837/1/config.json | 46 +++++++++++++++++++ .../tests/fixture/issues/6837/1/input.js | 25 ++++++++++ .../tests/fixture/issues/6837/1/output.js | 20 ++++++++ .../tests/fixture/issues/6837/2/config.json | 46 +++++++++++++++++++ .../tests/fixture/issues/6837/2/input.js | 16 +++++++ .../tests/fixture/issues/6837/2/output.js | 13 ++++++ .../issues/firebase-firestore/1/output.js | 4 +- .../chunks/357-72bd409f1472b1b8/output.js | 5 +- .../fixture/next/wrap-contracts/output.js | 21 +++++---- 11 files changed, 195 insertions(+), 18 deletions(-) create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/1/config.json create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/1/input.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/1/output.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/2/config.json create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/2/input.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/6837/2/output.js diff --git a/crates/swc/tests/fixture/issues-6xxx/6729/output/index.js b/crates/swc/tests/fixture/issues-6xxx/6729/output/index.js index baa943f7394..055a206dfe2 100644 --- a/crates/swc/tests/fixture/issues-6xxx/6729/output/index.js +++ b/crates/swc/tests/fixture/issues-6xxx/6729/output/index.js @@ -1,5 +1,8 @@ export async function foo() { - undefined_var_1 && await a({ - replace: undefined_var_2 ? 1 : 2 - }); + if (undefined_var_1) { + let replace; + replace = undefined_var_2 ? 1 : 2, await a({ + replace + }); + } } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs index ca9b6db5e42..4b4fd60d233 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs @@ -1479,7 +1479,13 @@ where ) }; - if b.is_lit() || b.is_class() || b.is_fn_expr() || b.is_arrow() { + if b.is_lit() + || b.is_class() + || b.is_fn_expr() + || b.is_arrow() + || b.is_await_expr() + || b.is_yield_expr() + { return Ok(false); } diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/config.json new file mode 100644 index 00000000000..e24c2f770eb --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/config.json @@ -0,0 +1,46 @@ +{ + "arguments": false, + "arrows": true, + "booleans": true, + "booleans_as_integers": false, + "collapse_vars": true, + "comparisons": true, + "computed_props": true, + "conditionals": true, + "dead_code": true, + "directives": true, + "drop_console": false, + "drop_debugger": true, + "evaluate": true, + "expression": false, + "hoist_funs": false, + "hoist_props": true, + "hoist_vars": false, + "if_return": true, + "join_vars": true, + "keep_classnames": false, + "keep_fargs": true, + "keep_fnames": false, + "keep_infinity": false, + "loops": true, + "negate_iife": true, + "properties": true, + "reduce_funcs": false, + "reduce_vars": false, + "side_effects": true, + "switches": true, + "typeofs": true, + "unsafe": false, + "unsafe_arrows": false, + "unsafe_comps": false, + "unsafe_Function": false, + "unsafe_math": false, + "unsafe_symbols": false, + "unsafe_methods": false, + "unsafe_proto": false, + "unsafe_regexp": false, + "unsafe_undefined": false, + "unused": true, + "const_to_let": true, + "pristine_globals": true +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/input.js new file mode 100644 index 00000000000..34fe5b6f1de --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/input.js @@ -0,0 +1,25 @@ +class Class1 { } + +function isClass2(node) { + return node instanceof Class2; +} + +Class1.isClass2 = isClass2; +export class Class2 extends Class1 { + constructor() { + super(); + this.method1 = async () => { + let var1; + const function1 = () => { }; + + var1 = await Class2.method2(); + await function1() + .then(() => { + console.log(var1); + }) + .catch(); + }; + } + + static async method2() { } +} \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/output.js new file mode 100644 index 00000000000..5d2b6ec43e2 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/1/output.js @@ -0,0 +1,20 @@ +class Class1 { +} +function isClass2(node) { + return node instanceof Class2; +} +Class1.isClass2 = isClass2; +export class Class2 extends Class1 { + constructor(){ + super(); + this.method1 = async ()=>{ + let var1; + const function1 = ()=>{}; + var1 = await Class2.method2(); + await function1().then(()=>{ + console.log(var1); + }).catch(); + }; + } + static async method2() {} +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/config.json new file mode 100644 index 00000000000..e24c2f770eb --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/config.json @@ -0,0 +1,46 @@ +{ + "arguments": false, + "arrows": true, + "booleans": true, + "booleans_as_integers": false, + "collapse_vars": true, + "comparisons": true, + "computed_props": true, + "conditionals": true, + "dead_code": true, + "directives": true, + "drop_console": false, + "drop_debugger": true, + "evaluate": true, + "expression": false, + "hoist_funs": false, + "hoist_props": true, + "hoist_vars": false, + "if_return": true, + "join_vars": true, + "keep_classnames": false, + "keep_fargs": true, + "keep_fnames": false, + "keep_infinity": false, + "loops": true, + "negate_iife": true, + "properties": true, + "reduce_funcs": false, + "reduce_vars": false, + "side_effects": true, + "switches": true, + "typeofs": true, + "unsafe": false, + "unsafe_arrows": false, + "unsafe_comps": false, + "unsafe_Function": false, + "unsafe_math": false, + "unsafe_symbols": false, + "unsafe_methods": false, + "unsafe_proto": false, + "unsafe_regexp": false, + "unsafe_undefined": false, + "unused": true, + "const_to_let": true, + "pristine_globals": true +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/input.js new file mode 100644 index 00000000000..7c3e7faa920 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/input.js @@ -0,0 +1,16 @@ +export class Class2 extends Class1 { + constructor() { + this.method1 = async () => { + let var1; + const function1 = () => { }; + + var1 = await Class2.method2(); + await function1() + .then(() => { + console.log(var1); + }) + }; + } + + static async method2() { } +} \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/output.js new file mode 100644 index 00000000000..55cb4640609 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/6837/2/output.js @@ -0,0 +1,13 @@ +export class Class2 extends Class1 { + constructor(){ + this.method1 = async ()=>{ + let var1; + const function1 = ()=>{}; + var1 = await Class2.method2(); + await function1().then(()=>{ + console.log(var1); + }); + }; + } + static async method2() {} +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/firebase-firestore/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/firebase-firestore/1/output.js index b2ca3419d54..f3f5703f684 100644 --- a/crates/swc_ecma_minifier/tests/fixture/issues/firebase-firestore/1/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/issues/firebase-firestore/1/output.js @@ -4055,7 +4055,7 @@ return (null === s || t.snapshotVersion.compareTo(s.snapshotVersion) > 0) && (n.Un = n.Un.insert(t.targetId, t), n.qn.set(e, t.targetId)), t; }); }(n.localStore, Ee(e)), r = n.sharedClientState.addLocalQueryTarget(t.targetId); - i = await sc(n, e, s = t.targetId, "current" === r), n.isPrimaryClient && co(n.remoteStore, t); + s = t.targetId, i = await sc(n, e, s, "current" === r), n.isPrimaryClient && co(n.remoteStore, t); } return i; } @@ -4617,7 +4617,7 @@ verifyOperationInProgress() {} async Sc() { let t; - do await (t = this._c); + do t = this._c, await t; while (t !== this._c) } Dc(t) { diff --git a/crates/swc_ecma_minifier/tests/fixture/next/octokit/static/chunks/357-72bd409f1472b1b8/output.js b/crates/swc_ecma_minifier/tests/fixture/next/octokit/static/chunks/357-72bd409f1472b1b8/output.js index 032ce899e62..69def6f6537 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/octokit/static/chunks/357-72bd409f1472b1b8/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/octokit/static/chunks/357-72bd409f1472b1b8/output.js @@ -69,11 +69,12 @@ return null != this._events[name] ? this._events[name].length : 0; } async trigger(name, ...args) { + var promises; try { if ("debug" !== name && this.trigger("debug", `Event triggered: ${name}`, args), null == this._events[name]) return; return this._events[name] = this._events[name].filter(function(listener) { return "none" !== listener.status; - }), (await Promise.all(this._events[name].map(async (listener)=>{ + }), promises = this._events[name].map(async (listener)=>{ var returned; if ("none" !== listener.status) { "once" === listener.status && (listener.status = "none"); @@ -84,7 +85,7 @@ return this.trigger("error", error), null; } } - }))).find(function(x) { + }), (await Promise.all(promises)).find(function(x) { return null != x; }); } catch (error) { diff --git a/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js b/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js index 7e6930dc023..56b4dcd69a9 100644 --- a/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js +++ b/crates/swc_ecma_minifier/tests/fixture/next/wrap-contracts/output.js @@ -3034,7 +3034,7 @@ if (this.isComplete) throw Error("Upload is already complete"); if ("" !== this.lastResponseError ? this.totalErrors++ : this.totalErrors = 0, 100 === this.totalErrors) throw Error(`Unable to complete upload: ${this.lastResponseStatus}: ${this.lastResponseError}`); let delay = "" === this.lastResponseError ? 0 : Math.max(this.lastRequestTimeEnd + ERROR_DELAY - Date.now(), ERROR_DELAY); - if (delay > 0 && await new Promise((res)=>setTimeout(res, delay -= delay * Math.random() * 0.3)), this.lastResponseError = "", !this.txPosted) { + if (delay > 0 && (delay -= delay * Math.random() * 0.3, await new Promise((res)=>setTimeout(res, delay))), this.lastResponseError = "", !this.txPosted) { await this.postTransaction(); return; } @@ -3619,7 +3619,7 @@ if (jwk || "undefined" != typeof window && window.arweaveWallet) { if (jwk && "use_wallet" !== jwk) { transaction.setOwner(jwk.n); - let rawSignature = await this.crypto.sign(jwk, await transaction.getSignatureData(), options), id = await this.crypto.hash(rawSignature); + let dataToSign = await transaction.getSignatureData(), rawSignature = await this.crypto.sign(jwk, dataToSign, options), id = await this.crypto.hash(rawSignature); transaction.setSignature({ id: ArweaveUtils.bufferTob64Url(id), owner: jwk.n, @@ -4059,7 +4059,7 @@ this.driver = crypto.subtle; } async generateJWK() { - let jwk = await this.driver.exportKey("jwk", (await this.driver.generateKey({ + let cryptoKey = await this.driver.generateKey({ name: "RSA-PSS", modulusLength: 4096, publicExponent: new Uint8Array([ @@ -4072,7 +4072,7 @@ } }, !0, [ "sign" - ])).privateKey); + ]), jwk = await this.driver.exportKey("jwk", cryptoKey.privateKey); return { kty: jwk.kty, e: jwk.e, @@ -4460,7 +4460,7 @@ if (this.isComplete) throw Error("Upload is already complete"); if ("" !== this.lastResponseError ? this.totalErrors++ : this.totalErrors = 0, 100 === this.totalErrors) throw Error(`Unable to complete upload: ${this.lastResponseStatus}: ${this.lastResponseError}`); let delay = "" === this.lastResponseError ? 0 : Math.max(this.lastRequestTimeEnd + ERROR_DELAY - Date.now(), ERROR_DELAY); - if (delay > 0 && await new Promise((res)=>setTimeout(res, delay -= delay * Math.random() * 0.3)), this.lastResponseError = "", !this.txPosted) { + if (delay > 0 && (delay -= delay * Math.random() * 0.3, await new Promise((res)=>setTimeout(res, delay))), this.lastResponseError = "", !this.txPosted) { await this.postTransaction(); return; } @@ -4942,7 +4942,7 @@ if (jwk || "undefined" != typeof window && window.arweaveWallet) { if (jwk && "use_wallet" !== jwk) { transaction.setOwner(jwk.n); - let rawSignature = await this.crypto.sign(jwk, await transaction.getSignatureData(), options), id = await this.crypto.hash(rawSignature); + let dataToSign = await transaction.getSignatureData(), rawSignature = await this.crypto.sign(jwk, dataToSign, options), id = await this.crypto.hash(rawSignature); transaction.setSignature({ id: ArweaveUtils.bufferTob64Url(id), owner: jwk.n, @@ -20975,7 +20975,7 @@ const { definitionLoader , interactionsLoader , executorFactory , stateEvaluator } = this.warp, benchmark = Benchmark_1.Benchmark.measure(), cachedState = await stateEvaluator.latestAvailableState(contractTxId, upToSortKey); this.logger.debug('cache lookup', benchmark.elapsed()), benchmark.reset(); const evolvedSrcTxId = Evolve_1.Evolve.evolvedSrcTxId(null === (_a = null == cachedState ? void 0 : cachedState.cachedValue) || void 0 === _a ? void 0 : _a.state); - return this.logger.debug('Cached state', cachedState, upToSortKey), cachedState && cachedState.sortKey == upToSortKey ? (this.logger.debug('State fully cached, not loading interactions.'), (forceDefinitionLoad || evolvedSrcTxId) && (handler = await executorFactory.create(contractDefinition = await definitionLoader.load(contractTxId, evolvedSrcTxId), this._evaluationOptions))) : ([contractDefinition, sortedInteractions] = await Promise.all([ + return this.logger.debug('Cached state', cachedState, upToSortKey), cachedState && cachedState.sortKey == upToSortKey ? (this.logger.debug('State fully cached, not loading interactions.'), (forceDefinitionLoad || evolvedSrcTxId) && (contractDefinition = await definitionLoader.load(contractTxId, evolvedSrcTxId), handler = await executorFactory.create(contractDefinition, this._evaluationOptions))) : ([contractDefinition, sortedInteractions] = await Promise.all([ definitionLoader.load(contractTxId, evolvedSrcTxId), interactions ? Promise.resolve(interactions) : await interactionsLoader.load(contractTxId, null == cachedState ? void 0 : cachedState.sortKey, this.getToSortKey(upToSortKey), this._evaluationOptions) ]), (null == cachedState ? void 0 : cachedState.sortKey) && (sortedInteractions = sortedInteractions.filter((i)=>i.sortKey.localeCompare(null == cachedState ? void 0 : cachedState.sortKey) > 0)), upToSortKey && (sortedInteractions = sortedInteractions.filter((i)=>0 >= i.sortKey.localeCompare(upToSortKey))), this.logger.debug('contract and interactions load', benchmark.elapsed()), null == this._parentContract && sortedInteractions.length && (this._rootSortKey = sortedInteractions[sortedInteractions.length - 1].sortKey), handler = await executorFactory.create(contractDefinition, this._evaluationOptions)), { @@ -21737,7 +21737,8 @@ }, innerWritesInteractions = await this.loadPages(innerWritesVariables); this.logger.debug('Inner writes interactions length:', innerWritesInteractions.length), interactions = interactions.concat(innerWritesInteractions); } - let sortedInteractions = await this.sorter.sort(interactions = interactions.filter((i)=>i.node.block && i.node.block.id && i.node.block.height)); + interactions = interactions.filter((i)=>i.node.block && i.node.block.id && i.node.block.height); + let sortedInteractions = await this.sorter.sort(interactions); return fromSortKey && toSortKey ? sortedInteractions = sortedInteractions.filter((i)=>i.node.sortKey.localeCompare(fromSortKey) > 0 && 0 >= i.node.sortKey.localeCompare(toSortKey)) : fromSortKey && !toSortKey ? sortedInteractions = sortedInteractions.filter((i)=>i.node.sortKey.localeCompare(fromSortKey) > 0) : !fromSortKey && toSortKey && (sortedInteractions = sortedInteractions.filter((i)=>0 >= i.node.sortKey.localeCompare(toSortKey))), this.logger.debug('All loaded interactions:', { from: fromSortKey, to: toSortKey, @@ -21750,10 +21751,10 @@ const txInfos = transactions.edges.filter((tx)=>bundledTxsFilter(tx)); for(; transactions.pageInfo.hasNextPage;){ const cursor = transactions.edges[MAX_REQUEST - 1].cursor; - transactions = await this.getNextPage(variables = { + variables = { ...variables, after: cursor - }), txInfos.push(...transactions.edges.filter((tx)=>bundledTxsFilter(tx))); + }, transactions = await this.getNextPage(variables), txInfos.push(...transactions.edges.filter((tx)=>bundledTxsFilter(tx))); } return txInfos; }